C (ภาษาโปรแกรม)

จากวิกิพีเดีย สารานุกรมเสรี
ข้ามไปที่การนำทาง ข้ามไปที่การค้นหา

ข้อความตัวพิมพ์ใหญ่ serif สีฟ้าอ่อนบนพื้นหลังสีขาวและตัวอักษร sans-serif สีฟ้าอ่อนขนาดใหญ่มาก C
กระบวนทัศน์หลายกระบวนทัศน์ : จำเป็น ( ขั้นตอน ), โครงสร้าง
ออกแบบโดยDennis Ritchie
นักพัฒนาANSI X3J11 ( ANSI C ); ISO/IEC JTC1 (คณะกรรมการวิชาการร่วม 1) / SC22 (คณะอนุกรรมการ 22) / WG14 (คณะทำงาน 14) (ISO C)
ปรากฏตัวครั้งแรก2515 ; 50 ปีที่แล้ว[2] ( 2515 )
ปล่อยที่มั่นคง
C17 / มิถุนายน 2561 ; 3 ปีที่แล้ว ( 2018-06 )
ปล่อยตัวอย่าง
C2x ( N2731 ) / 18 ตุลาคม 2564 ; 6 เดือนที่แล้ว[3] ( 2564-10-18 )
วินัยการพิมพ์คงที่อ่อนแอประจักษ์ระบุ _ _
OSข้ามแพลตฟอร์ม
นามสกุลไฟล์.c, .h
เว็บไซต์www .iso .org /standard /74528 .html
www .open-std .org /jtc1 /sc22 /wg14 /
การใช้งานหลัก
pcc , GCC , Clang , Intel C , C++Builder , Microsoft Visual C++ , Watcom C
ภาษาถิ่น
พายุไซโคลน , Unified Parallel C , Split-C , Cilk , C*
ได้รับอิทธิพลจาก
B ( BCPL , CPL ), ALGOL 68 , [4] การประกอบ , PL/I , FORTRAN
ได้รับอิทธิพล
มากมาย : AMPL , AWK , csh , C++ , C-- , C# , Objective-C , D , Go , Java , JavaScript , JS++ , Julia , Limbo , LPC , Perl , PHP , Pike , กำลัง ประมวลผล , Python , Rust , Seed7 , วาลา , เวริล็อก (HDL), [5] Nim, ซิก

C ( / ˈ s /ตามตัวอักษรc ) เป็นภาษาโปรแกรมคอมพิวเตอร์เอนกประสงค์ สร้างขึ้นในปี 1970 โดยDennis RitchieและBell Labsและยังคงใช้กันอย่างแพร่หลายและมีอิทธิพลอย่างมาก ด้วยการออกแบบ คุณสมบัติของ C สะท้อนถึงความสามารถของ CPU ที่เป็นเป้าหมายอย่างชัดเจน พบการใช้งานที่ยาวนานในระบบปฏิบัติการไดรเวอร์อุปกรณ์ส แต็ โปรโตคอลแม้ว่าจะลดลงสำหรับซอฟต์แวร์แอปพลิเคชันและพบได้ทั่วไปในสถาปัตยกรรมคอมพิวเตอร์ที่มีตั้งแต่ซูเปอร์คอมพิวเตอร์ ที่ใหญ่ที่สุดไปจนถึง ไมโครคอนโทรลเลอร์และระบบฝังตัวที่เล็กที่สุด

ตัวต่อจากภาษาโปรแกรมB , C ได้รับการพัฒนาขึ้นที่Bell LabsโดยDennis Ritchieระหว่างปี 1972 และ 1973 เพื่อสร้างยูทิลิตี้ที่ทำงานบนUnix มันถูกนำไปใช้กับการนำเคอร์เนลของระบบปฏิบัติการ Unix ไปใช้อีกครั้ง [6]ในช่วงปี 1980 C ค่อยๆ ได้รับความนิยม มันได้กลายเป็นหนึ่งใน ภาษาโปรแกรมที่ใช้กัน อย่างแพร่หลาย[7] [8]ด้วยคอมไพเลอร์ C พร้อมใช้งานสำหรับ สถาปัตยกรรมคอมพิวเตอร์และระบบปฏิบัติการที่ทันสมัยเกือบทั้งหมด C ได้รับมาตรฐานโดยANSIตั้งแต่ปี 1989 ( ANSI C ) และโดยองค์การระหว่างประเทศเพื่อการมาตรฐาน (ISO)

C เป็น ภาษา ขั้นตอน ที่ จำเป็น ซึ่งสนับสนุน การเขียนโปรแกรม แบบมีโครงสร้างขอบเขตของตัวแปรคำศัพท์และการเรียกซ้ำด้วยระบบประเภทส แตติก ได้รับการออกแบบมาให้คอมไพล์เพื่อให้เข้าถึงหน่วยความจำและโครงสร้างภาษาในระดับต่ำ ที่แมปกับ คำสั่งเครื่อง ได้อย่างมีประสิทธิภาพ ทั้งหมดนี้ รองรับรันไทม์น้อยที่สุด แม้จะมีความสามารถระดับต่ำ แต่ภาษาก็ได้รับการออกแบบมาเพื่อสนับสนุนการเขียนโปรแกรมข้ามแพลตฟอร์ม โปรแกรมC ที่ได้มาตรฐาน ซึ่งเขียนขึ้นพร้อมการ พกพาสามารถคอมไพล์สำหรับแพลตฟอร์มคอมพิวเตอร์และระบบปฏิบัติการที่หลากหลาย โดยมีการเปลี่ยนแปลงเล็กน้อยในซอร์สโค้ด [9]

ตั้งแต่ปี 2000 C ได้รับการจัดอันดับให้เป็นหนึ่งในสองภาษาชั้นนำอย่างสม่ำเสมอในดัชนี TIOBEซึ่งเป็นหน่วยวัดความนิยมของภาษาโปรแกรมมิ่ง [10]

ภาพรวม

Dennis Ritchie (ขวา) ผู้ประดิษฐ์ภาษาซี ร่วมกับKen Thompson

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

ข้อความต้นฉบับของโปรแกรม C มีรูปแบบอิสระโดยใช้เครื่องหมายอัฒภาคเป็นตัวคั่นคำสั่ง และ วงเล็บปีกกาสำหรับจัดกลุ่มกลุ่มคำ สั่ง

ภาษาซียังมีลักษณะดังต่อไปนี้:

  • ภาษามีคำหลักจำนวนเล็กน้อยคงที่ รวมทั้งชุดของขั้นตอนการควบคุมพื้นฐานทั้งหมด: if/else, for, do/while, , whileและ switchชื่อที่กำหนดโดยผู้ใช้จะไม่แตกต่างจากคำหลักด้วยเครื่องหมาย ใด ๆ
  • มีตัวดำเนินการเลขคณิต ระดับบิต และตรรกะจำนวนมาก: +, +=, ++, &, ||, ฯลฯ
  • สามารถดำเนินการ มอบหมายได้มากกว่าหนึ่งรายการในคำสั่งเดียว
  • ฟังก์ชั่น:
    • ค่าที่ส่งกลับของฟังก์ชันสามารถละเว้นได้ เมื่อไม่ต้องการ
    • ฟังก์ชันและข้อมูลพอยน์เตอร์ช่วยให้ เกิดความแตกต่าง ระหว่างรันไทม์เฉพาะกิจ
    • ฟังก์ชันไม่สามารถกำหนดได้ภายในขอบเขตคำศัพท์ของฟังก์ชันอื่นๆ
    • ตัวแปรสามารถกำหนดได้ภายในฟังก์ชัน โดยมีขอบเขต
    • ฟังก์ชันอาจเรียกตัวเอง ดังนั้นจึงรองรับการเรียกซ้ำ
  • การพิมพ์ข้อมูลเป็นแบบคงที่แต่ มีการ บังคับใช้อย่างอ่อน ข้อมูลทั้งหมดมีประเภท แต่ สามารถ แปลงโดยนัยได้
  • ผู้ใช้กำหนดเอง ( typedef ) และประเภทผสมเป็นไปได้
    • ชนิดข้อมูลรวมที่แตกต่างกัน ( struct) ช่วยให้สามารถเข้าถึงและกำหนดองค์ประกอบข้อมูลที่เกี่ยวข้องเป็นหน่วยได้
    • ยูเนี่ยนเป็นโครงสร้างที่มีสมาชิกทับซ้อนกัน เฉพาะสมาชิกล่าสุดที่เก็บไว้เท่านั้นที่ถูกต้อง
    • การทำดัชนี อาร์เรย์เป็นสัญกรณ์รอง ซึ่งกำหนดไว้ในแง่ของเลขคณิตพอยน์เตอร์ อาร์เรย์ไม่ใช่อ็อบเจ็กต์ระดับเฟิร์สคลาส ต่างจาก struct: ไม่สามารถกำหนดหรือเปรียบเทียบได้โดยใช้โอเปอเรเตอร์ในตัวเดียว ไม่มีคีย์เวิร์ด "array" ในการใช้งานหรือคำจำกัดความ แทน วงเล็บเหลี่ยมจะระบุอาร์เรย์แบบวากยสัมพันธ์แทน ตัวอย่างmonth[11]เช่น
    • ประเภทที่แจกแจงเป็นไปได้ด้วยenumคำหลัก พวกเขาสามารถแปลงเป็นจำนวนเต็มได้อย่างอิสระ
    • สตริงไม่ใช่ประเภทข้อมูลที่แตกต่างกัน แต่มีการใช้งาน ตามอัตภาพ เป็นอาร์เรย์อักขระที่สิ้นสุดด้วยค่า null
  • การเข้าถึง หน่วยความจำคอมพิวเตอร์ในระดับต่ำสามารถทำได้โดยการแปลงที่อยู่เครื่องเป็นตัวชี้
  • ขั้นตอน (รูทีนย่อยที่ไม่คืนค่า) เป็นกรณีพิเศษของฟังก์ชัน โดยมีประเภทการส่งคืนที่voidไม่ได้ พิมพ์
  • หน่วยความจำสามารถจัดสรรให้กับโปรแกรมที่มีการเรียกรูทีนไลบรารี
  • ตัวประมวลผลล่วงหน้าดำเนินการนิยามมาโครการรวมไฟล์ซอร์สโค้ด และ คอมไพล์ตาม เงื่อนไข
  • มีรูปแบบพื้นฐานของโมดูลา ร์ : ไฟล์สามารถคอมไพล์แยกกันและเชื่อมโยงเข้าด้วยกัน โดยสามารถควบคุมฟังก์ชันและออบเจ็กต์ข้อมูลที่จะมองเห็นได้ต่อไฟล์อื่นๆ ผ่านทางstaticและexternแอตทริบิวต์
  • ฟังก์ชันที่ซับซ้อน เช่นI/Oการ จัดการ สตริงและฟังก์ชันทางคณิตศาสตร์ ได้รับการมอบหมายอย่างสม่ำเสมอไปยังรูทีนของไลบรารี
  • โค้ดที่สร้างขึ้นหลังจากการคอมไพล์มีความต้องการที่ค่อนข้างตรงไปตรงมาบนแพลตฟอร์มพื้นฐาน ซึ่งทำให้เหมาะสำหรับการสร้างระบบปฏิบัติการและสำหรับใช้ในระบบฝังตัว

แม้ว่าภาษา C จะไม่รวมคุณลักษณะบางอย่างที่พบในภาษาอื่น (เช่นการวางแนววัตถุและการรวบรวมขยะ ) แต่สิ่งเหล่านี้สามารถนำไปใช้หรือจำลองได้ มักจะผ่านการใช้ไลบรารีภายนอก (เช่นGLib Object Systemหรือตัวรวบรวมขยะ Boehm )

ความสัมพันธ์กับภาษาอื่นๆ

ภาษาต่อมาหลายภาษายืมโดยตรงหรือโดยอ้อมจาก C รวมถึงC++ , C# , C shellของ Unix , D , Go , Java , JavaScript (รวมถึงtranspilers ), Julia , Limbo , LPC , Objective-C , Perl , PHP , Python , Ruby , Rust , Swift , VerilogและSystemVerilog (ภาษาคำอธิบายฮาร์ดแวร์) [5] ภาษาเหล่านี้ได้ดึงโครงสร้างการควบคุมและคุณลักษณะพื้นฐานอื่นๆ จาก C ออกมา ส่วนใหญ่ (Python เป็นข้อยกเว้นอย่างมาก) ยังแสดงไวยากรณ์ ที่คล้ายคลึงกันอย่างมาก กับ C และมักจะรวมนิพจน์ที่เป็นที่รู้จักและไวยากรณ์คำสั่งของ Cเข้ากับประเภทพื้นฐาน ระบบ แบบจำลองข้อมูล และความหมายที่อาจแตกต่างอย่างสิ้นเชิง

ประวัติ

การพัฒนาในช่วงต้น

เส้นเวลาของการพัฒนาภาษา
ปี ซี สแตนดาร์ด[9]
พ.ศ. 2515 การเกิด
พ.ศ. 2521 K&R C
1989/1990 ANSI Cและ ISO C
1999 C99
2011 C11
2017 C17
จะแจ้งภายหลัง C2x

ที่มาของ C นั้นเชื่อมโยงอย่างใกล้ชิดกับการพัฒนา ระบบปฏิบัติการ Unixซึ่งเดิมใช้ในภาษาแอสเซมบลีบนPDP-7โดย Dennis Ritchie และ Ken Thompson โดยผสมผสานแนวคิดหลายอย่างจากเพื่อนร่วมงาน ในที่สุด พวกเขาตัดสินใจย้ายระบบปฏิบัติการไปยังPDP- 11 Unix เวอร์ชัน PDP-11 ดั้งเดิมได้รับการพัฒนาในภาษาแอสเซมบลีด้วย [6]

บี

Thompson ต้องการภาษาการเขียนโปรแกรมเพื่อสร้างยูทิลิตี้สำหรับแพลตฟอร์มใหม่ ตอนแรกเขาพยายาม สร้างคอมไพเลอร์ Fortranแต่ไม่นานก็ล้มเลิกความคิดนี้ แต่เขาได้สร้างเวอร์ชันย่อของภาษาการเขียนโปรแกรมระบบBCPL ที่พัฒนาขึ้นเมื่อเร็วๆ นี้ แทน ไม่มีคำอธิบายอย่างเป็นทางการของ BCPL ในขณะนั้น[11]และ Thompson ได้แก้ไขรูปแบบไวยากรณ์ให้มีความชัดเจนน้อยลง และคล้ายกับALGOL แบบง่าย ที่รู้จักกันในชื่อ SMLGOL [12] ผลที่ได้คือสิ่งที่ทอมป์สันเรียกว่าบี [6]เขาอธิบาย B ว่า "ความหมาย BCPL พร้อมไวยากรณ์ SMALGOL จำนวนมาก" [12]เช่นเดียวกับBCPL B มีการบูต สแตรปคอมไพเลอร์เพื่ออำนวยความสะดวกในการพอร์ตไปยังเครื่องใหม่ [12]อย่างไรก็ตาม ในที่สุดยูทิลิตี้บางอย่างก็เขียนด้วย B เพราะมันช้าเกินไป และไม่สามารถใช้ประโยชน์จากคุณสมบัติ PDP-11 เช่น การ ระบุตำแหน่ง ไบต์ได้

B ใหม่และCรุ่น แรก

ในปีพ.ศ. 2514 ริตชี่เริ่มปรับปรุง B เพื่อใช้คุณลักษณะของ PDP-11 ที่ทรงพลังกว่า การเพิ่มที่สำคัญคือประเภทอักขระ เขาเรียกสิ่งนี้ว่า นิ บี [12] ทอมป์สันเริ่มใช้ NB เพื่อเขียน เคอร์เนล Unixและข้อกำหนดของเขากำหนดทิศทางของการพัฒนาภาษา [12] [13] จนถึงปี พ.ศ. 2515 มีการเพิ่มประเภทที่สมบูรณ์ยิ่งขึ้นในภาษา NB: NB มีอาร์เรย์ของintและchar; แต่ต่อมาได้มีการเพิ่มพอยน์เตอร์ ความสามารถในการสร้างพอยน์เตอร์ไปยังประเภทอื่น อาร์เรย์ของทั้งหมดนี้ ประเภทที่จะส่งคืนจากฟังก์ชัน อาร์เรย์ภายในนิพจน์กลายเป็นตัวชี้ มีการเขียนคอมไพเลอร์ใหม่และภาษาถูกเปลี่ยนชื่อเป็น C. [6]

คอมไพเลอร์ C และยูทิลิตี้บางอย่างที่ทำขึ้นนั้นรวมอยู่ในเวอร์ชัน2 Unix [14]

โครงสร้างและเคอร์เนลUnix เขียนใหม่

ที่เวอร์ชัน 4 Unixซึ่งเผยแพร่ในเดือนพฤศจิกายน พ.ศ. 2516 เคอร์เนลUnix ถูกนำไปใช้ใหม่อย่างกว้างขวางใน C. [6]ถึงเวลานี้ ภาษา C ได้รับคุณลักษณะที่มีประสิทธิภาพบางอย่างเช่นประเภท struct

ตัวประมวลผลล่วงหน้าเปิดตัวเมื่อประมาณปี 1973 โดยได้รับคำแนะนำจากAlan Snyderและยังรับรู้ถึงประโยชน์ของกลไกการรวมไฟล์ที่มีอยู่ใน BCPL และ PL/I เวอร์ชันดั้งเดิมให้เฉพาะไฟล์และการแทนที่สตริงอย่างง่าย: #includeและ#defineมาโครที่ไม่มีพารามิเตอร์ หลังจากนั้นไม่นาน ส่วนขยายนี้ขยายโดยMike Leskและ John Reiser เป็นส่วนใหญ่ เพื่อรวมมาโครเข้ากับอาร์กิวเมนต์และการรวบรวมแบบมีเงื่อนไข [6]

Unix เป็นหนึ่งในเคอร์เนลของระบบปฏิบัติการตัวแรกที่ใช้ภาษาอื่นที่ไม่ใช่แอสเซมบลี ตัวอย่างก่อนหน้านี้รวมถึง ระบบ Multics (ซึ่งเขียนในPL/I ) และMaster Control Program (MCP) สำหรับBurroughs B5000 (ซึ่งเขียนด้วยALGOL ) ในปี 1961 ในราวปี 1977 Ritchie และStephen C. Johnsonได้ทำการเปลี่ยนแปลงเพิ่มเติมใน ภาษาที่อำนวยความสะดวกในการพกพาระบบปฏิบัติการ Unix Portable C Compilerของ Johnson ทำหน้าที่เป็นพื้นฐานสำหรับการใช้งาน C หลายตัวบนแพลตฟอร์มใหม่ [13]

เคแอนด์อาร์ซี

ปกหนังสือThe C Programming Languageฉบับพิมพ์ครั้งแรก โดยBrian KernighanและDennis Ritchie

ในปี 1978 Brian KernighanและDennis Ritchieได้ตีพิมพ์The C Programming Language ฉบับพิมพ์ ครั้ง แรก [1]หนังสือเล่มนี้ ซึ่งรู้จักกันในชื่อโปรแกรมเมอร์ C ในชื่อK&R ทำหน้าที่เป็น ข้อกำหนดที่ไม่เป็นทางการของภาษา มาหลายปี เวอร์ชันของ C ที่อธิบายโดยทั่วไปจะเรียกว่า " K&R C " เนื่องจากเปิดตัวในปี 1978 จึงเรียกอีกอย่างว่าC78 [15]หนังสือฉบับที่สอง[16]ครอบคลุมมาตรฐาน ANSI C ในภายหลัง ดังอธิบายด้านล่าง

K&Rนำเสนอคุณสมบัติหลายภาษา:

  • ไลบรารี I/O มาตรฐาน
  • long intประเภทข้อมูล
  • unsigned intประเภทข้อมูล
  • ตัวดำเนินการกำหนดแบบผสมของแบบฟอร์ม(เช่น) ถูกเปลี่ยนเป็นรูปแบบ(นั่นคือ) เพื่อลบความกำกวมทางความหมายที่สร้างขึ้นโดยโครงสร้างเช่นซึ่งถูกตีความว่าเป็น(ลดลง10) แทนที่จะเป็นสิ่งที่ตั้งใจไว้(ปล่อยให้เป็น - 10).=op=-op=-=i=-10i =- 10ii = -10i

แม้หลังจากการตีพิมพ์มาตรฐาน ANSI ปี 1989 เป็นเวลาหลายปี K&R C ยังคงถูกมองว่าเป็น " ตัวหารร่วมที่ต่ำที่สุด " ซึ่งโปรแกรมเมอร์ภาษาซีจำกัดตัวเองเมื่อต้องการพกพาสูงสุด เนื่องจากคอมไพเลอร์รุ่นเก่าจำนวนมากยังคงใช้งานอยู่ และเนื่องจากเขียน K&R อย่างระมัดระวัง รหัส C สามารถถูกกฎหมาย Standard C ได้เช่นกัน

ในเวอร์ชันก่อนหน้าของ C เฉพาะฟังก์ชันที่ส่งคืนประเภทอื่นนอกเหนือจากที่intต้องประกาศหากใช้ก่อนกำหนดฟังก์ชัน ฟังก์ชันที่ใช้โดยไม่มีการประกาศล่วงหน้าจะถือว่าส่งคืนintประเภท

ตัวอย่างเช่น:

ยาวsome_function (); 
/* int */ other_function (); 

/* int */ calling_function () 
{
    การทดสอบแบบ ยาว1 ; 
    ลงทะเบียน/* int */ test2 ;  

    test1 = some_function ();  
    ถ้า( test1 > 1 )   
          ทดสอบ2 = 0 ;  
    อื่น
          test2 = other_function ();  
    ส่งคืนtest2 ; 
}

ตัวintระบุประเภทที่ใส่ความคิดเห็นสามารถละเว้นได้ใน K&R C แต่จำเป็นในมาตรฐานในภายหลัง

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

ในช่วงหลายปีหลังการตีพิมพ์ K&R C ได้มีการเพิ่มฟีเจอร์ต่างๆ ในภาษานี้ รองรับโดยคอมไพเลอร์จาก AT&T (โดยเฉพาะPCC [17] ) และผู้จำหน่ายรายอื่นๆ สิ่งเหล่านี้รวมถึง:

  • voidฟังก์ชัน (เช่น ฟังก์ชันที่ไม่มีค่าส่งคืน)
  • ฟังก์ชันส่งคืนstructหรือunionประเภท (แทนที่จะเป็นพอยน์เตอร์)
  • การกำหนดประเภทstructข้อมูล
  • จำแนกประเภท

ส่วนขยายจำนวนมากและการขาดข้อตกลงในไลบรารีมาตรฐานประกอบกับความนิยมของภาษาและความจริงที่ว่าไม่ใช่แม้แต่คอมไพเลอร์ Unix ที่ปรับใช้ข้อกำหนด K&R อย่างแม่นยำ นำไปสู่ความจำเป็นในการสร้างมาตรฐาน [ ต้องการการอ้างอิง ]

ANSI C และ ISO C

ในช่วงปลายทศวรรษ 1970 และ 1980 เวอร์ชัน C ถูกนำไปใช้กับคอมพิวเตอร์เมนเฟรมมินิ คอมพิวเตอร์ และไมโครคอมพิวเตอร์ที่หลากหลาย รวมถึงIBM PCเนื่องจากความนิยมเริ่มเพิ่มขึ้นอย่างมาก

ในปี 1983 American National Standards Institute (ANSI) ได้จัดตั้งคณะกรรมการ X3J11 เพื่อกำหนดข้อกำหนดมาตรฐานของ C. X3J11 ตามมาตรฐาน C ในการใช้งาน Unix; อย่างไรก็ตาม ส่วนที่ไม่ใช่แบบพกพาของไลบรารี Unix C ถูกส่งไปยังคณะทำงานIEEE 1003 เพื่อเป็นพื้นฐานสำหรับมาตรฐานPOSIX ปี 1988 ในปี 1989 มาตรฐาน C ได้รับการรับรองเป็น ANSI X3.159-1989 "Programming Language C" ภาษารุ่นนี้มักถูกเรียกว่าANSI C , Standard C หรือบางครั้ง C89

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

ANSI ก็เหมือนกับหน่วยงานมาตรฐานระดับประเทศอื่นๆ ที่ไม่ได้พัฒนามาตรฐาน C อย่างอิสระอีกต่อไป แต่ยังคงรักษามาตรฐาน C สากล ซึ่งดูแลโดยคณะทำงานISO/IEC JTC1/SC22 /WG14 การนำการปรับปรุงมาตรฐานสากลไปใช้ในระดับประเทศมักเกิดขึ้นภายในหนึ่งปีหลังจากเผยแพร่ ISO

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

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

ในกรณีที่โค้ดต้องคอมไพล์โดยคอมไพเลอร์ที่เป็นไปตามมาตรฐานหรือคอมไพเลอร์แบบ K&R C __STDC__สามารถใช้มาโครเพื่อแยกโค้ดออกเป็นส่วนมาตรฐานและ K&R เพื่อป้องกันการใช้งานคอมไพเลอร์แบบ K&R C ของฟีเจอร์ที่มีเฉพาะในสแตนดาร์ด ค.

หลังจากกระบวนการกำหนดมาตรฐาน ANSI/ISO ข้อกำหนดภาษา C ยังคงค่อนข้างคงที่เป็นเวลาหลายปี ในปี 1995 Normative Amendment 1 ของมาตรฐาน 1990 C (ISO/IEC 9899/AMD1:1995 หรือที่รู้จักกันอย่างไม่เป็นทางการว่า C95) ได้รับการตีพิมพ์ เพื่อแก้ไขรายละเอียดบางส่วนและเพิ่มการสนับสนุนเพิ่มเติมสำหรับชุดอักขระสากล [18]

C99

2542 ISO C.pdf

มาตรฐาน C ได้รับการแก้ไขเพิ่มเติมในช่วงปลายทศวรรษ 1990 ซึ่งนำไปสู่การตีพิมพ์ ISO/IEC 9899:1999 ในปี 1999 ซึ่งโดยทั่วไปจะเรียกว่า " C99 " นับตั้งแต่นั้นมาก็ได้รับการแก้ไขโดย Technical Corrigenda ถึงสามครั้ง (19)

C99 นำเสนอคุณลักษณะใหม่หลายอย่าง รวมถึงฟังก์ชันอินไลน์ประเภทข้อมูลใหม่หลาย ประเภท (รวมถึงlong long intและcomplexประเภทที่แสดงถึงจำนวนเชิงซ้อน ) อาร์เรย์ความยาวผันแปรและสมาชิกอาร์เรย์ที่ยืดหยุ่นการสนับสนุนที่ปรับปรุงสำหรับจุดลอยตัวIEEE 754 การรองรับ มาโครแบบแปรผัน (มาโครของตัวแปรarity ) และรองรับความคิดเห็นแบบบรรทัดเดียวที่ขึ้นต้นด้วย//เช่นเดียวกับในBCPLหรือ C++ สิ่งเหล่านี้จำนวนมากได้ถูกนำไปใช้เป็นส่วนขยายในคอมไพเลอร์ C หลายตัวแล้ว

C99 นั้นส่วนใหญ่เข้ากันได้กับ C90 แบบย้อนหลัง แต่จะเข้มงวดกว่าในบางแง่มุม โดยเฉพาะอย่างยิ่งการประกาศที่ไม่มีตัวระบุประเภทไม่ได้intสันนิษฐานโดยปริยาย อีกต่อไป มาโครมาตรฐาน__STDC_VERSION__ถูกกำหนดด้วยค่า199901Lเพื่อระบุว่ามีการรองรับ C99 GCC , Solaris Studioและคอมไพเลอร์ C อื่น ๆ รองรับคุณสมบัติใหม่จำนวนมากหรือทั้งหมดของ C99 อย่างไรก็ตาม คอมไพเลอร์ C ในMicrosoft Visual C++ใช้มาตรฐาน C89 และส่วนต่างๆ ของ C99 ที่จำเป็นสำหรับความเข้ากันได้กับC++ 11 [20] [ ต้องการการอัปเดต ]

นอกจากนี้ จำเป็นต้องมีการรองรับ ตัวระบุ Unicode (ชื่อตัวแปร / ฟังก์ชัน) ในรูปแบบของอักขระที่ใช้ Escape (เช่น\U0001f431) รองรับชื่อ Unicode แบบดิบหรือไม่ก็ได้

C11

ในปี 2550 งานเริ่มต้นในการแก้ไขมาตรฐาน C อีกครั้งซึ่งเรียกว่า "C1X" อย่างไม่เป็นทางการจนกว่าจะมีการเผยแพร่อย่างเป็นทางการในวันที่ 2011-12-08 คณะกรรมการมาตรฐาน C ได้นำแนวทางปฏิบัติมาใช้เพื่อจำกัดการนำคุณลักษณะใหม่ที่ไม่ได้รับการทดสอบโดยการใช้งานที่มีอยู่

มาตรฐาน C11 เพิ่มคุณสมบัติใหม่มากมายให้กับ C และไลบรารี รวมถึงมาโครทั่วไปประเภท โครงสร้างที่ไม่ระบุตัวตน การสนับสนุน Unicode ที่ได้รับการปรับปรุง การดำเนินการปรมาณู มัลติเธรดดิ้ง และฟังก์ชันตรวจสอบขอบเขต นอกจากนี้ยังทำให้บางส่วนของไลบรารี C99 ที่มีอยู่เป็นทางเลือก และปรับปรุงความเข้ากันได้กับ C++ มาโครมาตรฐาน__STDC_VERSION__ถูกกำหนด201112Lเพื่อระบุว่ารองรับ C11

C17

เผยแพร่ในเดือนมิถุนายน 2018 C17 เป็นมาตรฐานปัจจุบันสำหรับภาษาซี โดยไม่ได้นำเสนอฟีเจอร์ภาษาใหม่ มีเพียงการแก้ไขทางเทคนิค และการชี้แจงข้อบกพร่องใน C11 มาโครมาตรฐาน__STDC_VERSION__ถูกกำหนดเป็น201710L.

C2x

C2x เป็นชื่อที่ไม่เป็นทางการสำหรับการแก้ไขมาตรฐานภาษา C หลักถัดไป (หลัง C17) คาดว่าจะได้รับการโหวตในปี 2566 และจะถูกเรียกว่า C23 [21] [ ต้องการแหล่งที่ดีกว่า ]

ฝัง C

ในอดีต การเขียนโปรแกรม C แบบฝังต้องมีส่วนขยายที่ไม่เป็นมาตรฐานสำหรับภาษา C เพื่อรองรับคุณลักษณะที่แปลกใหม่ เช่นเลขคณิตแบบจุดตายตัวช่องหน่วยความจำที่แตกต่างกันหลายช่อง และการดำเนินการ I/O พื้นฐาน

ในปี 2008 คณะกรรมการมาตรฐาน C ได้ตีพิมพ์รายงานทางเทคนิคที่ขยายขอบเขตภาษา C [22]เพื่อแก้ไขปัญหาเหล่านี้โดยจัดให้มีมาตรฐานทั่วไปสำหรับการนำไปใช้งานทั้งหมดให้ยึดถือ ประกอบด้วยคุณลักษณะจำนวนหนึ่งที่ไม่มีใน C ปกติ เช่นเลขคณิตจุดคงที่ ช่องว่างที่อยู่ที่ระบุ และการกำหนดที่อยู่ฮาร์ดแวร์ I/O พื้นฐาน

ไวยากรณ์

C มีไวยากรณ์ที่เป็นทางการ ซึ่ง กำหนดโดยมาตรฐาน C [23]การลงท้ายบรรทัดโดยทั่วไปไม่สำคัญใน C; อย่างไรก็ตาม เส้นแบ่งเขตมีความสำคัญในระหว่างขั้นตอนก่อนการประมวลผล ความคิดเห็นอาจปรากฏขึ้นระหว่างตัวคั่น/*และ*/หรือ (ตั้งแต่ C99) ต่อ จากนี้ไป //จนสิ้นสุดบรรทัด ความคิดเห็นที่คั่นด้วย/*และ*/ไม่ซ้อน และลำดับของอักขระเหล่านี้จะไม่ถูกตีความเป็นตัวคั่นความคิดเห็น หากปรากฏอยู่ภายในสตริงหรือตัวอักษร [24]

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

ในฐานะที่เป็นภาษาที่จำเป็น C ใช้คำสั่งเพื่อระบุการกระทำ คำสั่งที่พบบ่อยที่สุดคือคำสั่งนิพจน์ซึ่งประกอบด้วยนิพจน์ที่จะประเมิน ตามด้วยเครื่องหมายอัฒภาค เนื่องจากผลข้างเคียงของการประเมิน อาจเรียก ฟังก์ชันและ กำหนดค่าตัวแปรใหม่ได้ ในการแก้ไขการดำเนินการตามลำดับปกติของคำสั่ง C ได้จัดเตรียมคำสั่งควบคุมโฟลว์หลายรายการที่ระบุโดยคีย์เวิร์ดที่สงวนไว้ การเขียนโปรแกรมแบบมีโครงสร้างได้รับการสนับสนุนโดยif… [ else] การดำเนินการตามเงื่อนไข และโดยdowhile, while, และforการดำเนินการซ้ำ (วนซ้ำ) ดิforคำสั่งมีนิพจน์การเริ่มต้น การทดสอบ และการเริ่มต้นใหม่แยกจากกัน ซึ่งสามารถละเว้นบางส่วนหรือทั้งหมดได้ breakและcontinueสามารถใช้เพื่อออกจากคำสั่งวนรอบที่อยู่ด้านในสุดหรือข้ามไปที่การเริ่มต้นใหม่ นอกจากนี้ยังมีคำสั่งที่ไม่มีโครงสร้างgotoซึ่งแยกสาขาโดยตรงกับป้ายกำกับ ที่กำหนด ภายในฟังก์ชัน switchเลือก a caseที่จะดำเนินการตามค่าของนิพจน์จำนวนเต็ม

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

Kernighan และ Ritchie กล่าวในบทนำของThe C Programming Languageว่า "C ก็เหมือนกับภาษาอื่นๆ ที่มีรอยตำหนิ ตัวดำเนินการบางตัวมีลำดับความสำคัญที่ผิด บางส่วนของไวยากรณ์อาจดีกว่านี้" [25]มาตรฐาน C ไม่ได้พยายามที่จะแก้ไขข้อบกพร่องเหล่านี้หลายอย่าง เนื่องจากผลกระทบของการเปลี่ยนแปลงดังกล่าวในซอฟต์แวร์ที่มีอยู่แล้ว

ชุดตัวละคร

ชุดอักขระต้นทาง C พื้นฐานประกอบด้วยอักขระต่อไปนี้:

ขึ้นบรรทัดใหม่ระบุจุดสิ้นสุดของบรรทัดข้อความ ไม่จำเป็นต้องสอดคล้องกับอักขระตัวเดียวจริง ๆ แม้ว่า C จะถือว่ามันเป็นตัวเดียวเพื่อความสะดวก

อักขระที่เข้ารหัสแบบหลายไบต์เพิ่มเติมอาจใช้ในตัวอักษรสตริง แต่ไม่สามารถพกพาได้ ทั้งหมด มาตรฐาน C ล่าสุด ( C11 ) อนุญาตให้ ฝังอักขระUnicodeข้ามชาติ แบบเคลื่อนย้ายได้ภายในข้อความต้นฉบับ C โดยใช้ \uXXXXหรือ\UXXXXXXXXเข้ารหัส (โดยที่Xหมายถึงอักขระฐานสิบหก) แม้ว่าคุณลักษณะนี้จะยังไม่มีการใช้งานอย่างกว้างขวาง

ชุดอักขระการเรียกใช้ C พื้นฐานประกอบด้วยอักขระเดียวกัน พร้อมด้วยการแสดงแทนalert , backspace และ carriage return การสนับสนุน รันไทม์สำหรับชุดอักขระแบบขยายเพิ่มขึ้นด้วยการแก้ไขมาตรฐาน C แต่ละครั้ง

คำสงวน

C89 มีคำสงวนไว้ 32 คำหรือที่เรียกว่าคำหลักซึ่งเป็นคำที่ไม่สามารถใช้เพื่อวัตถุประสงค์อื่นนอกเหนือจากที่กำหนดไว้ล่วงหน้า:

C99 สงวนไว้อีกห้าคำ:

C11 สงวนคำอีกเจ็ดคำ: [26]

  • _Alignas
  • _Alignof
  • _Atomic
  • _Generic
  • _Noreturn
  • _Static_assert
  • _Thread_local

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

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

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

C ใช้ตัวดำเนินการ=(ใช้ในคณิตศาสตร์เพื่อแสดงความเท่าเทียมกัน) เพื่อระบุการมอบหมาย ตามแบบอย่างของFortranและPL/Iแต่ต่างจากALGOLและอนุพันธ์ของ ALGOL C ใช้ตัวดำเนินการ==เพื่อทดสอบความเท่าเทียมกัน ความคล้ายคลึงกันระหว่างโอเปอเรเตอร์สองตัวนี้ (การมอบหมายและความเท่าเทียมกัน) อาจส่งผลให้มีการใช้ตัวหนึ่งแทนตัวอื่นโดยไม่ได้ตั้งใจ และในหลายกรณี ข้อผิดพลาดจะไม่สร้างข้อความแสดงข้อผิดพลาด (แม้ว่าคอมไพเลอร์บางตัวจะสร้างคำเตือน) ตัวอย่างเช่น นิพจน์เงื่อนไขif (a == b + 1)อาจเขียนผิดพลาดเป็นif (a = b + 1)ซึ่งจะถูกประเมินว่าเป็นจริงถ้าaไม่เป็นศูนย์หลังจากการมอบหมาย (28)

ลำดับความสำคัญของตัวดำเนินการ C นั้นไม่ง่ายเสมอไป ตัวอย่างเช่น ตัวดำเนินการ==ผูกแน่นกว่า (ดำเนินการก่อน) ตัวดำเนินการ&(ระดับบิต AND) และ|(ระดับบิต OR) ในนิพจน์เช่นx & 1 == 0ซึ่งจะต้องเขียนราวกับ(x & 1) == 0ว่าเป็นความตั้งใจของผู้เขียนโค้ด [29]

ตัวอย่าง "สวัสดีชาวโลก"

"สวัสดีชาวโลก!" โปรแกรมโดยBrian Kernighan (1978)

ตัวอย่าง " สวัสดีชาวโลก " ซึ่งปรากฏในK&R ฉบับพิมพ์ครั้งแรก ได้กลายเป็นต้นแบบของโปรแกรมเบื้องต้นในตำราการเขียนโปรแกรมส่วนใหญ่ โปรแกรมจะพิมพ์ "hello, world" ลงในเอาต์พุตมาตรฐานซึ่งมักจะเป็นหน้าจอแสดงเทอร์มินัลหรือหน้าจอ

เวอร์ชันดั้งเดิมคือ: [30]

หลัก()
{
    printf ( "สวัสดีชาวโลก\n " );
}

โปรแกรม "สวัสดีชาวโลก" ที่ได้มาตรฐานคือ: [a]

#include <stdio.h> 

int หลัก( เป็นโมฆะ) 
{
    printf ( "สวัสดีชาวโลก\n " );
}

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

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

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

บรรทัดถัดไปจะเรียก (เปลี่ยนการดำเนินการไปที่) ฟังก์ชันที่ชื่อprintfซึ่งในกรณีนี้มาจากไลบรารีระบบ ในการเรียกนี้printfฟังก์ชันจะถูกส่งผ่าน (ให้มาด้วย) อาร์กิวเมนต์เดียว ที่อยู่ของอักขระตัวแรกในสตริงตามตัว "hello, world\n"อักษร สตริงตามตัวอักษรเป็นอาร์เรย์ ที่ไม่มีชื่อ ซึ่งมีองค์ประกอบประเภทcharซึ่งตั้งค่าโดยอัตโนมัติโดยคอมไพเลอร์ด้วยอักขระที่มีค่า 0 สุดท้ายเพื่อทำเครื่องหมายจุดสิ้นสุดของอาร์เรย์ ( printfจำเป็นต้องทราบ) เป็นEscape Sequence\nที่C แปลเป็น อักขระขึ้น บรรทัดใหม่ซึ่งในเอาต์พุตหมายถึงจุดสิ้นสุดของบรรทัดปัจจุบัน ค่าส่งคืนของprintfฟังก์ชั่นเป็นประเภทintแต่จะถูกละทิ้งอย่างเงียบ ๆ เนื่องจากไม่ได้ใช้งาน (โปรแกรมที่ระมัดระวังมากขึ้นอาจทดสอบค่าที่ส่งกลับเพื่อพิจารณาว่าprintfฟังก์ชันทำงานสำเร็จหรือไม่) อัฒภาค;ยุติคำสั่ง

วงเล็บปีกกาปิดแสดงถึงจุดสิ้นสุดของโค้ดสำหรับmainฟังก์ชัน ตามข้อกำหนดของ C99 และใหม่กว่าmainฟังก์ชันนี้ไม่เหมือนกับฟังก์ชันอื่นใด จะส่งคืนค่าโดยปริยาย0เมื่อไปถึง}ฟังก์ชันที่ยุติฟังก์ชัน (ก่อนหน้าreturn 0;นี้จำเป็นต้องมีคำสั่งที่ชัดเจน) สิ่งนี้ถูกตีความโดยระบบรันไทม์ว่าเป็นรหัสออกที่บ่งชี้การดำเนินการที่ประสบความสำเร็จ [31]

ประเภทข้อมูล

ระบบประเภทใน C เป็นแบบคงที่และพิมพ์ไม่ชัดซึ่งทำให้คล้ายกับระบบประเภท ลูกหลาน ALGOLเช่นPascal [32] มีชนิดในตัวสำหรับจำนวนเต็มขนาดต่างๆ ทั้งแบบมีเครื่องหมายและไม่ได้ลงนามเลขทศนิยมและประเภทที่แจกแจง ( enum) ประเภทจำนวนเต็มcharมักใช้สำหรับอักขระแบบไบต์เดี่ยว C99 เพิ่มประเภทข้อมูลบูลีนอกจากนี้ยังมีประเภทที่ได้รับรวมถึงอาร์เรย์ , พอยน์เตอร์ , เร็กคอร์ด ( struct) และยูเนียน ( union)

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

บางคนพบว่าไวยากรณ์การประกาศของ C นั้นไม่เป็นธรรมชาติ โดยเฉพาะอย่างยิ่งสำหรับ พอย น์เตอร์ ของ ฟังก์ชัน (แนวคิดของริตชี่คือการประกาศตัวระบุในบริบทที่คล้ายกับการใช้งาน: " การประกาศสะท้อนถึงการใช้ ".) [33]

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

พอยน์เตอร์

C รองรับการใช้ พ อยน์เตอร์ ซึ่งเป็นประเภทของการอ้างอิงที่บันทึกที่อยู่หรือตำแหน่งของวัตถุหรือฟังก์ชันในหน่วยความจำ สามารถนำพอยน์เตอร์ไปอ้างอิงเพื่อเข้าถึงข้อมูลที่เก็บไว้ที่ที่อยู่ที่ชี้ไป หรือเพื่อเรียกใช้ฟังก์ชันชี้ไปที่ สามารถจัดการพอยน์เตอร์ได้โดยใช้การกำหนดหรือเลขคณิต พอยน์ เตอร์ การแสดงค่ารันไทม์ของค่าพอยน์เตอร์มักจะเป็นที่อยู่หน่วยความจำดิบ (อาจเสริมด้วยฟิลด์ออฟเซ็ตภายในคำ) แต่เนื่องจากประเภทของพอยน์เตอร์รวมประเภทของสิ่งที่ชี้ไป นิพจน์รวมถึงพอยน์เตอร์จึงสามารถตรวจสอบประเภทได้ ในเวลารวบรวม เลขคณิตของตัวชี้จะถูกปรับขนาดโดยอัตโนมัติตามขนาดของประเภทข้อมูลที่ชี้ไปที่ ตัวชี้ถูกใช้เพื่อวัตถุประสงค์หลายอย่างใน C. Text stringsมักถูกจัดการโดยใช้พอยน์เตอร์ในอาร์เรย์ของอักขระ การ จัดสรรหน่วยความจำแบบไดนามิกดำเนินการโดยใช้พอยน์เตอร์ ข้อมูลหลายประเภท เช่นต้นไม้มักถูกนำไปใช้เป็นออบเจ็กต์ที่จัดสรรแบบไดนามิกstructซึ่งเชื่อมโยงเข้าด้วยกันโดยใช้พอยน์เตอร์ ตัวชี้ไปยังฟังก์ชันมีประโยชน์สำหรับการส่งฟังก์ชันเป็นอาร์กิวเมนต์ไปยังฟังก์ชันที่มีลำดับสูงกว่า (เช่นqsortหรือbsearch ) หรือเป็นการเรียกกลับที่เรียกใช้โดยตัวจัดการเหตุการณ์ [31]

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

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

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

อาร์เรย์

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

เนื่องจากอาร์เรย์เข้าถึงได้เสมอ (มีผล) ผ่านพอยน์เตอร์ โดยปกติแล้วการเข้าถึงอาร์เรย์จะไม่ตรวจสอบเทียบกับขนาดอาร์เรย์พื้นฐาน แม้ว่าคอมไพเลอร์บางตัวอาจมีการตรวจสอบขอบเขตเป็นตัวเลือก [34] [35] การละเมิดขอบเขตอาร์เรย์จึงเป็นไปได้และสามารถนำไปสู่ผลกระทบต่างๆ รวมถึงการเข้าถึงหน่วยความจำที่ผิดกฎหมาย ความเสียหายของข้อมูลบัฟเฟอร์เกินและข้อยกเว้นรันไทม์

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

ตัวอย่างต่อไปนี้โดยใช้ C ที่ทันสมัย ​​(C99 หรือใหม่กว่า) แสดงการจัดสรรอาร์เรย์สองมิติบนฮีปและการใช้การจัดทำดัชนีอาร์เรย์หลายมิติสำหรับการเข้าถึง (ซึ่งสามารถใช้การตรวจสอบขอบเขตบนคอมไพเลอร์ C หลายตัว):

int func ( int N , int M )    
{
  float ( * p )[ N ][ M ] = malloc ( sizeof * p );    
  ถ้า( ! p ) 
    กลับ-1 ; 
  สำหรับ( int i = 0 ; i < N ; i ++ )        
    สำหรับ( int j = 0 ; j < M ; j ++ )        
      ( * p )[ i ][ j ] = i + j ;    
  print_array ( N , M , p );  
  ฟรี( p );
  กลับ1 ; 
}

และนี่คือการใช้งานที่คล้ายกันโดยใช้ ฟีเจอร์ Auto VLA ของ C99 :

int func ( int N , int M )    
{
  // ข้อควรระวัง: ควรทำการตรวจสอบเพื่อให้แน่ใจว่า N*M*sizeof(float) ไม่เกินขีดจำกัดสำหรับ VLA อัตโนมัติและอยู่ในขนาดสแต็กที่มีอยู่ 
ลอยp [ N ][ M ]; // auto VLA ถูกเก็บไว้บน stack และขนาดเมื่อมีการเรียกใช้ฟังก์ชันสำหรับ( int i = 0 ; i < N ; i ++ )    
          
    สำหรับ( int j = 0 ; j < M ; j ++ )        
      p [ i ][ j ] = ฉัน+ j ;    
  // ไม่จำเป็นต้อง free(p) เนื่องจากมันจะหายไปเมื่อออกจากฟังก์ชันพร้อมกับสแต็กเฟรมที่เหลือ
return 1 ;   
}

ความสามารถในการแลกเปลี่ยนอาร์เรย์–ตัวชี้

สัญกรณ์ตัวห้อยx[i](ซึ่งxกำหนดตัวชี้) คือsyntax sugarสำหรับ*(x+i). [36]การใช้ประโยชน์จากความรู้ของคอมไพเลอร์เกี่ยวกับประเภทพอยน์เตอร์ ที่อยู่ที่x + iชี้ไปไม่ใช่ที่อยู่ฐาน (ชี้ไปที่x) เพิ่มขึ้นทีละiไบต์ แต่ถูกกำหนดให้เป็นที่อยู่ฐานที่เพิ่มขึ้นโดยiคูณด้วยขนาดของ องค์ประกอบที่xชี้ไปที่ ดังนั้นx[i]กำหนดi+1องค์ประกอบที่ th ของอาร์เรย์

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

ขนาดรวมของอาร์เรย์xสามารถกำหนดได้โดยใช้sizeofนิพจน์ประเภทอาร์เรย์ ขนาดขององค์ประกอบสามารถกำหนดได้โดยใช้ตัวดำเนินการsizeofกับองค์ประกอบใด ๆ ที่ไม่ได้อ้างอิงของอาร์เรย์ดังAเช่นใน n = sizeof A[0]จำนวนองค์ประกอบในอาร์เรย์ที่ประกาศAสามารถกำหนดsizeof A / sizeof A[0]ได้ดังนี้ โปรดทราบว่าหากมีเพียงตัวชี้ไปยังองค์ประกอบแรกซึ่งมักจะเป็นกรณีในโค้ด C เนื่องจากการแปลงอัตโนมัติที่อธิบายไว้ข้างต้น ข้อมูลเกี่ยวกับประเภทเต็มของอาร์เรย์และความยาวของอาร์เรย์จะสูญหายไป

การจัดการหน่วยความจำ

หน้าที่ที่สำคัญที่สุดอย่างหนึ่งของภาษาการเขียนโปรแกรมคือการจัดเตรียมสิ่งอำนวยความสะดวกสำหรับการจัดการหน่วยความจำและวัตถุที่เก็บไว้ในหน่วยความจำ C มีวิธีหลักสามวิธีในการจัดสรรหน่วยความจำสำหรับวัตถุ: [31]

  • การ จัดสรรหน่วยความจำแบบคงที่ : พื้นที่สำหรับวัตถุมีให้ในไบนารีในเวลารวบรวม; วัตถุเหล่านี้มีขอบเขต (หรืออายุการใช้งาน) ตราบใดที่ไบนารีที่มีพวกมันถูกโหลดลงในหน่วยความจำ
  • การ จัดสรรหน่วยความจำอัตโนมัติ : สามารถจัดเก็บอ็อบเจ็กต์ชั่วคราวบนสแต็ก และพื้นที่นี้จะว่างและนำกลับมาใช้ใหม่โดยอัตโนมัติหลังจากบล็อกที่ประกาศออกมา
  • การ จัดสรรหน่วยความจำแบบไดนามิก : บล็อกของหน่วยความจำขนาดที่กำหนดเองสามารถร้องขอได้ในขณะใช้งานโดยใช้ฟังก์ชันไลบรารี เช่นmallocจากพื้นที่ของหน่วยความจำที่เรียกว่าฮีบล็อกเหล่านี้ยังคงมีอยู่จนกว่าจะมีอิสระในการนำกลับมาใช้ใหม่ในภายหลังโดยเรียกฟังก์ชันไลบรารีreallocหรือfree

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

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

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

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

ห้องสมุด

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

ไลบรารี C ที่พบบ่อยที่สุดคือไลบรารีมาตรฐาน Cซึ่งกำหนดโดยมาตรฐาน ISOและANSI Cและมาพร้อมกับการใช้งาน C ทุกครั้ง (การใช้งานที่กำหนดเป้าหมายไปยังสภาพแวดล้อมที่จำกัด เช่นระบบฝังตัวอาจมีเฉพาะชุดย่อยของไลบรารีมาตรฐานเท่านั้น) ไลบรารีนี้รองรับสตรีมอินพุตและเอาต์พุต การจัดสรรหน่วยความจำ คณิตศาสตร์ สตริงอักขระ และค่าเวลา ส่วนหัวมาตรฐานแยกกันหลายรายการ (เช่นstdio.h) ระบุอินเทอร์เฟซสำหรับสิ่งอำนวยความสะดวกเหล่านี้และไลบรารีมาตรฐานอื่นๆ

ฟังก์ชันไลบรารี C ทั่วไปอีกชุดหนึ่งใช้โดยแอปพลิเคชันที่กำหนดเป้าหมายเฉพาะสำหรับระบบ UnixและUnixโดยเฉพาะฟังก์ชันที่ให้ส่วนต่อประสานกับเคอร์เนล ฟังก์ชันเหล่า นี้ มีรายละเอียดในมาตรฐานต่างๆ เช่นPOSIXและSingle UNIX Specification

เนื่องจากหลายโปรแกรมเขียนด้วยภาษาซี จึงมีไลบรารีอื่นๆ ให้เลือกมากมาย ไลบรารี่มักเขียนด้วยภาษา C เนื่องจากคอมไพเลอร์ C สร้างโค้ดอ็อบเจ็กต์ที่ มี ประสิทธิภาพ จากนั้นโปรแกรมเมอร์จะสร้างอินเทอร์เฟซไปยังไลบรารีเพื่อให้รูทีนสามารถใช้งานได้จากภาษาระดับสูงเช่นJava , PerlและPython [31]

การจัดการไฟล์และสตรีม

ไฟล์อินพุตและเอาต์พุต (I/O) ไม่ได้เป็นส่วนหนึ่งของภาษา C แต่ถูกจัดการโดยไลบรารี (เช่น ไลบรารีมาตรฐาน C) และไฟล์ส่วนหัวที่เกี่ยวข้อง (เช่นstdio.h) การจัดการไฟล์โดยทั่วไปจะดำเนินการผ่าน I/O ระดับสูงซึ่งทำงานผ่านสตรีสตรีมมาจากมุมมองนี้เป็นโฟลว์ข้อมูลที่เป็นอิสระจากอุปกรณ์ ในขณะที่ไฟล์เป็นอุปกรณ์ที่เป็นรูปธรรม I/O ระดับสูงจะทำผ่านการเชื่อมโยงของสตรีมกับไฟล์ ในไลบรารีมาตรฐาน C บัฟเฟอร์ (พื้นที่หน่วยความจำหรือคิว) ถูกใช้ชั่วคราวเพื่อจัดเก็บข้อมูลก่อนที่จะถูกส่งไปยังปลายทางสุดท้าย ซึ่งช่วยลดเวลาที่ใช้ในการรออุปกรณ์ที่ช้ากว่า เช่นฮาร์ดไดรฟ์หรือโซลิดสเตตไดรฟ์. ฟังก์ชัน I/O ระดับต่ำไม่ได้เป็นส่วนหนึ่งของไลบรารี C มาตรฐาน[ ต้องการคำชี้แจง ]แต่โดยทั่วไปแล้วเป็นส่วนหนึ่งของการเขียนโปรแกรม "bare Metal" (การเขียนโปรแกรมที่ไม่ขึ้นกับระบบปฏิบัติการ ใดๆ เช่นการเขียนโปรแกรมแบบฝัง ส่วนใหญ่ ) มีข้อยกเว้นบางประการ การใช้งานรวมถึง I/O ระดับต่ำ

เครื่องมือภาษา

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

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

นอกจากนี้ยังมีคอมไพเลอร์ ไลบรารี และกลไกระดับระบบปฏิบัติการสำหรับการดำเนินการที่ไม่ใช่ส่วนมาตรฐานของ C เช่น การตรวจสอบขอบเขตสำหรับอาร์เรย์ การตรวจจับบัฟเฟอร์ล้นการ ทำให้เป็น อนุกรมการติดตามหน่วยความจำแบบไดนามิก และ การรวบรวมขยะอัตโนมัติ

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

ใช้

ภาษาการเขียนโปรแกรม C

C ใช้กันอย่างแพร่หลายสำหรับการเขียนโปรแกรมระบบในการใช้งานระบบปฏิบัติการและแอปพลิเคชันระบบฝังตัว [38]ด้วยเหตุผลหลายประการ:

  • โค้ดที่สร้างขึ้นหลังจากการคอมไพล์ไม่ต้องการคุณลักษณะของระบบมากมาย และสามารถเรียกใช้จากโค้ดสำหรับบูตบางอย่างในลักษณะที่ตรงไปตรงมา ซึ่งง่ายต่อการดำเนินการ
  • โดยทั่วไป คำสั่งและนิพจน์ภาษาซีจะจับคู่กับลำดับของคำสั่งสำหรับโปรเซสเซอร์เป้าหมายได้อย่างดี และด้วยเหตุนี้จึงมีความต้องการทรัพยากรระบบในเวลาทำงานต่ำ - ดำเนินการได้รวดเร็ว
  • ภาษาทำให้ง่ายต่อการวางโครงสร้างบนบล็อกของข้อมูลไบนารี ทำให้สามารถเข้าใจ สำรวจ และแก้ไขข้อมูลได้ มันสามารถเขียนโครงสร้างข้อมูล แม้แต่ระบบไฟล์
  • ภาษารองรับชุดตัวดำเนินการจำนวนมาก รวมถึงการจัดการบิต สำหรับเลขคณิตและตรรกะจำนวนเต็ม และอาจมีขนาดแตกต่างกันของจำนวนจุดลอยตัว มันสามารถประมวลผลข้อมูลที่มีโครงสร้างอย่างเหมาะสมได้อย่างมีประสิทธิภาพ
  • ฮาร์ดแวร์แพลตฟอร์มสามารถเข้าถึงได้ด้วยพอยน์เตอร์และประเภท punningดังนั้นคุณลักษณะเฉพาะของระบบ (เช่นControl/Status Registers , I/O registers ) สามารถกำหนดค่าและใช้กับโค้ดที่เขียนในภาษา C ได้ ซึ่งจะโต้ตอบได้ดีกับแพลตฟอร์มที่กำลังทำงานอยู่
  • ขึ้นอยู่กับตัวเชื่อมโยงและสภาพแวดล้อม โค้ด C ยังสามารถเรียกไลบรารี่ที่เขียนด้วยภาษาแอสเซมบลีและอาจเรียกจากภาษาแอสเซมบลี - มันทำงานร่วมกับโค้ดอื่นได้ดี
  • C มีระบบนิเวศที่สมบูรณ์และกว้างมาก รวมถึงคอมไพเลอร์โอเพนซอร์ส ดีบักเกอร์ และยูทิลิตี้ และเป็นมาตรฐานโดยพฤตินัย เป็นไปได้ว่าไดรเวอร์มีอยู่แล้วใน C หรือมีสถาปัตยกรรม CPU ที่คล้ายคลึงกันในฐานะแบ็คเอนด์ของคอมไพเลอร์ C ดังนั้นจึงลดแรงจูงใจในการเลือกภาษาอื่น

ในอดีต บางครั้ง C ถูกใช้เพื่อการพัฒนาเว็บโดยใช้Common Gateway Interface (CGI) เป็น "เกตเวย์" สำหรับข้อมูลระหว่างเว็บแอปพลิเคชัน เซิร์ฟเวอร์ และเบราว์เซอร์ [39] C อาจได้รับเลือกมากกว่าภาษาที่แปล แล้ว เนื่องจากความเร็ว ความเสถียร และความพร้อมใช้งานที่เกือบจะเป็นสากล [40] ไม่ใช่เรื่องปกติอีกต่อไปสำหรับการพัฒนาเว็บที่จะทำใน C, [41]และเครื่องมือการพัฒนาเว็บ อื่น ๆ อีกมากมายที่ มีอยู่

ผลที่ตามมาของความพร้อมใช้งานและประสิทธิภาพในวงกว้างของ C คือคอมไพเลอร์ไลบรารีและล่ามของภาษาการเขียนโปรแกรมอื่น ๆ มักจะถูกนำมาใช้ใน C ตัวอย่างเช่นการใช้งานอ้างอิงของPython , Perl , RubyและPHPนั้นเขียนด้วย C

C ช่วยให้โปรแกรมเมอร์สร้างการใช้งานอัลกอริธึมและโครงสร้างข้อมูลอย่างมีประสิทธิภาพ เนื่องจากเลเยอร์ของสิ่งที่เป็นนามธรรมจากฮาร์ดแวร์นั้นบาง และโอเวอร์เฮดก็ต่ำ ซึ่งเป็นเกณฑ์สำคัญสำหรับโปรแกรมที่มีการประมวลผลสูง ตัวอย่างเช่นGNU Multiple Precision Arithmetic Library , GNU Scientific Library , MathematicaและMATLABนั้นเขียนเป็นภาษา C ทั้งหมดหรือบางส่วน หลายภาษารองรับการเรียกใช้ฟังก์ชันไลบรารีใน C ตัวอย่างเช่นNumPyเฟรมเวิ ร์กที่ใช้ Pythonใช้ C สำหรับค่าสูง - ด้านประสิทธิภาพและการโต้ตอบกับฮาร์ดแวร์

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

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

ข้อจำกัด

พลังของภาษาแอสเซมบลีและความสะดวกของ ... ภาษาแอสเซมบลี

—  เดนนิส ริตชี่[42]

แม้ว่า C จะได้รับความนิยม มีอิทธิพล และประสบความสำเร็จอย่างมาก แต่ก็มีข้อเสีย ได้แก่:

  • การจัดการหน่วยความจำไดนามิกมาตรฐานด้วยmallocและfreeมีแนวโน้มที่จะเกิดข้อผิดพลาด ข้อบกพร่องรวมถึง: หน่วยความจำรั่วเมื่อหน่วยความจำถูกจัดสรรแต่ไม่ว่าง; และเข้าถึงหน่วยความจำที่ว่างไว้ก่อนหน้านี้
  • การใช้พอยน์เตอร์และการจัดการหน่วยความจำโดยตรงหมายความว่าหน่วยความจำอาจเสียหายได้ อาจเป็นเพราะข้อผิดพลาดของโปรแกรมเมอร์ หรือการตรวจสอบข้อมูลที่ไม่ดีไม่เพียงพอ
  • เนื่องจากโค้ดที่สร้างโดยคอมไพเลอร์มีการตรวจสอบเพียงเล็กน้อย จึงมีภาระสำหรับโปรแกรมเมอร์ที่จะต้องพิจารณาผลลัพธ์ที่เป็นไปได้ทั้งหมด และป้องกันการโอเวอร์รันบัฟเฟอร์ การตรวจสอบขอบเขตอาร์เรย์ สแตกโอเวอร์โฟลว์ หน่วยความจำหมด สภาพการแข่งขัน การแยกเธรด ฯลฯ
  • การใช้พอยน์เตอร์และการจัดการรันไทม์ของวิธีการเหล่านี้ อาจมีสองวิธีในการเข้าถึงข้อมูลเดียวกัน (นามแฝง) ซึ่งไม่สามารถกำหนดได้ในเวลารวบรวม ซึ่งหมายความว่าการเพิ่มประสิทธิภาพบางอย่างที่อาจใช้ได้กับภาษาอื่นไม่สามารถทำได้ใน C. FORTRAN ถือว่าเร็วกว่า
  • ฟังก์ชันไลบรารีมาตรฐานบางอย่าง เช่นscanfอาจทำให้บัฟเฟอร์เกิน
  • มีการกำหนดมาตรฐานที่จำกัดในการสนับสนุนตัวแปรระดับต่ำในโค้ดที่สร้างขึ้น เช่น: ข้อตกลงการเรียก ใช้ฟังก์ชันที่แตกต่าง กัน ข้อตกลงการบรรจุโครงสร้างที่แตกต่างกัน การเรียงลำดับไบต์ที่แตกต่างกันภายในจำนวนเต็มที่มากกว่า (รวมถึง endianness) ในการใช้งานหลายภาษา ตัวเลือกเหล่านี้บางตัวอาจได้รับการจัดการด้วยคำสั่งตัวประมวลผลล่วงหน้า#pragma[ 43]และบางตัวมีคำหลักเพิ่มเติม เช่น ใช้__cdeclแบบแผนการเรียก แต่คำสั่งและตัวเลือกไม่ได้รับการสนับสนุนอย่างสม่ำเสมอ [44]
  • ภาษาไม่สนับสนุนการวางแนววัตถุ การวิปัสสนา การประเมินนิพจน์รันไทม์ ข้อมูลทั่วไป ข้อยกเว้นโดยตรง
  • มีการป้องกันการใช้คุณลักษณะภาษาที่ไม่เหมาะสม ซึ่งอาจนำไปสู่รหัสที่ไม่สามารถบำรุงรักษาได้

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

ภาษาที่เกี่ยวข้อง

กราฟ ดัชนีTIOBEแสดงการเปรียบเทียบความนิยมของภาษาโปรแกรมต่างๆ[45]

ภาษาซีมีอิทธิพลทั้งทางตรงและทางอ้อมในภายหลัง เช่นC# , D , Go , Java , JavaScript , Limbo , LPC , Perl , PHP , Python และ C เชลล์ของUnix [46]อิทธิพลที่แพร่หลายมากที่สุดคือวากยสัมพันธ์; ภาษาทั้งหมดที่กล่าวถึงรวมคำสั่งและไวยากรณ์นิพจน์ (ไม่มากก็น้อย) ของ Cกับระบบประเภท แบบจำลองข้อมูล และ/หรือโครงสร้างโปรแกรมขนาดใหญ่ที่แตกต่างจากภาษา C ซึ่งบางครั้งอาจแตกต่างอย่างสิ้นเชิง

มีล่ามภาษา C หรือ Near-C หลายตัว รวมถึงChและCINTซึ่งสามารถใช้สำหรับการเขียนสคริปต์ได้เช่นกัน

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

ภาษา การ เขียนโปรแกรม C++ (เดิมชื่อ "C with Classes ") ถูกคิดค้นโดยBjarne Stroustrupเพื่อเป็นแนวทางในการจัดหา ฟังก์ชัน เชิงวัตถุด้วยไวยากรณ์ที่คล้าย C [48] ​​C++ เพิ่มความแรงในการพิมพ์ การกำหนดขอบเขต และเครื่องมืออื่นๆ ที่เป็นประโยชน์ในการเขียนโปรแกรมเชิงวัตถุ และอนุญาตให้เขียนโปรแกรมทั่วไปผ่านเทมเพลต เกือบ superset ของ C, C++ รองรับ C ส่วนใหญ่แล้ว โดยมีข้อยกเว้นบางประการ

Objective-Cเดิมเป็นเลเยอร์ "บาง" มากบน C และยังคงเป็นsuperset ที่เข้มงวด ของ C ที่อนุญาตให้เขียนโปรแกรมเชิงวัตถุโดยใช้กระบวนทัศน์การพิมพ์ไดนามิก / สแตติกไฮบริด Objective-C มาจากไวยากรณ์ของทั้ง C และSmalltalk : ไวยากรณ์ที่เกี่ยวข้องกับการประมวลผลล่วงหน้า นิพจน์ การประกาศฟังก์ชัน และการเรียกใช้ฟังก์ชันนั้นสืบทอดมาจาก C ในขณะที่ไวยากรณ์สำหรับคุณลักษณะเชิงวัตถุนั้นเริ่มแรกจาก Smalltalk

นอกจากC++และObjective-C , Ch , CilkและUnified Parallel Cยังเป็น supersets ของ C อีกด้วย

ดูเพิ่มเติมที่

หมายเหตุ

  1. ^ โค้ดตัวอย่างดั้งเดิมจะคอมไพล์บนคอมไพเลอร์สมัยใหม่ส่วนใหญ่ที่ไม่อยู่ในโหมดการปฏิบัติตามมาตรฐานที่เข้มงวด แต่ไม่เป็นไปตามข้อกำหนดของ C89 หรือ C99 อย่างครบถ้วน อันที่จริง C99 ต้องการให้สร้างข้อความวินิจฉัย
  2. ^ จริงๆ แล้ว ฟังก์ชันmainมีสองอาร์กิวเมนต์int argcและchar *argv[]ตามลำดับ ซึ่งสามารถใช้เพื่อจัดการอาร์กิวเมนต์บรรทัดคำสั่ง มาตรฐาน ISO C (ส่วนที่ 5.1.2.2.1) กำหนดให้ต้องmainรองรับทั้งสองรูปแบบ ซึ่งเป็นการปฏิบัติพิเศษที่ไม่สามารถใช้ได้กับฟังก์ชันอื่นๆ

อ้างอิง

  1. อรรถเป็น Kernighan, Brian W. ; Ritchie, Dennis M. (กุมภาพันธ์ 2521) ภาษาการเขียนโปรแกรม C (ฉบับที่ 1) หน้าผาแองเกิลวูด รัฐนิวเจอร์ซี : Prentice Hall ISBN 978-0-110163-0.
  2. Ritchie (1993) : "ทอมป์สันพยายามสร้างระบบที่เข้ารหัสในเวอร์ชันแรกๆ ของ C—ก่อนสร้างโครงสร้าง—ในปี 1972 แต่เลิกใช้ความพยายาม"
  3. ^ ฟรูเดริกา (13 ธันวาคม 2020). "ประวัติซี" . ที่cppreference.com เก็บถาวรจากต้นฉบับเมื่อ 24 ตุลาคม 2020 . สืบค้นเมื่อ24 ตุลาคม 2020 .
  4. ^ Ritchie (1993) : "รูปแบบขององค์ประกอบประเภทที่ C นำมาใช้นั้นเป็นหนี้จำนวนมากกับ Algol 68 แม้ว่าอาจจะไม่เกิดขึ้นในรูปแบบที่สมัครพรรคพวกของ Algol จะอนุมัติ"
  5. ^ a b " Verilog HDL (และ C)" (PDF ) โรงเรียนวิจัยวิทยาการคอมพิวเตอร์ที่มหาวิทยาลัยแห่งชาติออสเตรเลีย 3 มิถุนายน 2553 เก็บถาวรจากต้นฉบับ(PDF)เมื่อวันที่ 6 พฤศจิกายน 2556 . สืบค้นเมื่อ19 สิงหาคม 2013 . ทศวรรษ 1980: ; เปิดตัว Verilog ครั้งแรก ; Verilog ได้รับแรงบันดาลใจจากภาษาการเขียนโปรแกรม C
  6. อรรถa b c d e f Ritchie (1993)
  7. ^ "ความนิยมภาษาโปรแกรม" . 2552. เก็บถาวรจากต้นฉบับเมื่อ 16 มกราคม 2552 . สืบค้นเมื่อ16 มกราคม 2009 .
  8. ^ "ดัชนีชุมชนการเขียนโปรแกรม TIOBE" . 2552. เก็บถาวรจากต้นฉบับเมื่อ 4 พฤษภาคม 2552 . สืบค้นเมื่อ 6 พฤษภาคม 2552
  9. ^ a b "ประวัติของ C" . th.cppreference.com . เก็บจากต้นฉบับเมื่อ 29 พฤษภาคม 2018 . สืบค้นเมื่อ28 พฤษภาคม 2018 .
  10. ^ "ดัชนี TIOBE ประจำเดือนตุลาคม 2564" . สืบค้นเมื่อ7 ตุลาคมพ.ศ. 2564 .
  11. ริตชี่, เดนนิส. "BCPL เป็น B ถึง C" . เก็บจากต้นฉบับเมื่อ 12 ธันวาคม 2019 . สืบค้นเมื่อ10 กันยายน 2019 .
  12. a b c d e Jensen, Richard (9 ธันวาคม 2020). ""เรื่องโง่ๆ ที่ต้องทำ"—ต้นกำเนิดของ C" . Ars Technica . สืบค้นเมื่อ28 มีนาคม 2022
  13. อรรถเป็น จอห์นสัน เซาท์แคโรไลนา ; ริตชี่ ดีเอ็ม (1978) "การพกพาของโปรแกรม C และระบบ UNIX" เบลล์ ซิสเต็ม เทค เจ . 57 (6): 2021–2048. CiteSeerX 10.1.1.138.35 . ดอย : 10.1002/j.1538-7305.1978.tb02141.x . S2CID 17510065 .  (หมายเหตุ: PDF เป็นการสแกน OCR ของต้นฉบับ และมีการแสดง "IBM 370" เป็น "IBM 310")
  14. แมคอิลรอย, แมรี่แลนด์ (1987). ผู้อ่าน Research Unix: คำอธิบายประกอบที่ตัดตอนมาจากคู่มือโปรแกรมเมอร์, 1971–1986 (PDF) (รายงานทางเทคนิค) ซีเอสทีอาร์ เบลล์แล็บ หน้า 10. 139. เก็บถาวร(PDF)จากต้นฉบับเมื่อ 11 พฤศจิกายน 2017 . สืบค้นเมื่อ1 กุมภาพันธ์ 2558 .
  15. ^ "หน้าคู่มือ C". FreeBSD คู่มือข้อมูลเบ็ดเตล็ด (FreeBSD 13.0 ed.) 30 พฤษภาคม 2554 เก็บถาวร จาก ต้นฉบับเมื่อ 21 มกราคม 2564 สืบค้นเมื่อ15 มกราคม 2021 . [1] จัด เก็บเมื่อ 21 มกราคม พ.ศ. 2564 ที่Wayback Machine
  16. เคอร์นิแกน, ไบรอัน ดับเบิลยู. ; Ritchie, Dennis M. (มีนาคม 2531) ภาษาการเขียนโปรแกรม C (ฉบับที่ 2) หน้าผาแองเกิลวูด รัฐนิวเจอร์ซี : Prentice Hall ISBN 978-0-110362-7.
  17. สตรูสทรัป, บียาร์น (2002). การแข่งขันระหว่างพี่น้อง: C และ C++ (PDF) (รายงาน) เอทีแอนด์ทีแล็บ เก็บถาวร(PDF)จากต้นฉบับเมื่อ 24 สิงหาคม 2014 . สืบค้นเมื่อ14 เมษายน 2014 .
  18. ^ C ความซื่อสัตย์ องค์การระหว่างประเทศเพื่อการมาตรฐาน 30 มีนาคม 2538 เก็บถาวรจากต้นฉบับเมื่อ 25 กรกฎาคม 2018 . สืบค้นเมื่อ24 กรกฎาคม 2018 .
  19. ^ "JTC1/SC22/WG14 – C" . หน้าแรก . ไอเอสโอ/ไออีซี. เก็บจากต้นฉบับเมื่อ 12 กุมภาพันธ์ 2018 . สืบค้นเมื่อ2 มิถุนายน 2554 .
  20. ^ แอนดรูว์ บินสต็อก (12 ตุลาคม 2554) “สัมภาษณ์เฮิร์บซัทเทอร์” . ดร.ด็อบส์ . เก็บถาวรจากต้นฉบับเมื่อ 2 สิงหาคม 2013 . สืบค้นเมื่อ7 กันยายน 2556 .
  21. ^ "แก้ไข C23 ตาราง WG 14 N 2759" (PDF ) www.open-std.orgครับ เก็บถาวร(PDF)จากต้นฉบับ เมื่อวันที่ 24 มิถุนายน พ.ศ. 2564 . สืบค้นเมื่อ10 ตุลาคม 2021 .
  22. ^ "TR 18037: เอ็มเบ็ดเด็ด C" (PDF ) ISO / ไออีซี. เก็บถาวร(PDF)จากต้นฉบับเมื่อ 25 กุมภาพันธ์ 2021 . สืบค้นเมื่อ26 กรกฎาคม 2011 .
  23. ฮาร์บิสัน ซามูเอล พี.; สตีล, กาย แอล. (2002). C: คู่มืออ้างอิง (ฉบับที่ 5) หน้าผาแองเกิลวูด รัฐนิวเจอร์ซี : Prentice Hall ISBN 978-0-13-089592-9.มี ไวยากรณ์ BNFสำหรับ C.
  24. ^ Kernighan & Ritchie (1996) , พี. 192.
  25. ^ Kernighan & Ritchie (1978) , พี. 3.
  26. ^ "ร่างคณะกรรมการ ISO/IEC 9899:201x (ISO C11)" (PDF ) เก็บถาวร(PDF)จากต้นฉบับเมื่อ 22 ธันวาคม 2017 . สืบค้นเมื่อ16 กันยายน 2554 .
  27. ^ Kernighan & Ritchie (1996) , pp. 192, 259.
  28. ^ "10 ข้อผิดพลาดในการเขียนโปรแกรมทั่วไปใน C++ " Cs.ucr.edu. เก็บถาวรจากต้นฉบับเมื่อ 21 ตุลาคม 2551 . สืบค้นเมื่อ26 มิถุนายน 2552 .
  29. ชูลทซ์, โธมัส (2004). C และ 8051 (ฉบับที่ 3) Otsego, MI: PageFree Publishing Inc. p. 20. ISBN 978-1-58961-237-2. เก็บถาวรจากต้นฉบับเมื่อ 29 กรกฎาคม 2020 . สืบค้นเมื่อ10 กุมภาพันธ์ 2555 .
  30. ^ Kernighan & Ritchie (1978) , พี. 6.
  31. a b c d e f g Klemens, Ben (2013). ศตวรรษที่ 21ค. โอเรล ลี่ มีเดีย . ISBN 978-1-4493-2714-9.
  32. ^ ฟิวเออร์ อลัน อาร์.; Gehani, Narain H. (มีนาคม 2525) "การเปรียบเทียบภาษาโปรแกรม C และ Pascal". การสำรวจ คอมพิวเตอร์ACM 14 (1): 73–92. ดอย : 10.1145/356869.356872 . S2CID 3136859 . 
  33. ^ Kernighan & Ritchie (1996) , พี. 122.
  34. ^ ตัวอย่างเช่น gcc ให้ _FORTIFY_SOURCE "คุณสมบัติความปลอดภัย: คอมไพล์ตรวจสอบบัฟเฟอร์เวลา (FORTIFY_SOURCE) " fedoraproject.org. เก็บถาวรจากต้นฉบับเมื่อ 7 มกราคม 2550 . สืบค้นเมื่อ5 สิงหาคม 2555 .
  35. ^ เอี่ยมศิริวงศ์, โอภาศ (2559). การเขียนโปรแกรมด้วย C . กรุงเทพมหานคร ประเทศไทย: บริษัท ซีเอ็ดดูเคชั่น จำกัด (มหาชน) หน้า 225–230. ISBN 978-616-08-2740-4.
  36. เรย์มอนด์ เอริก เอส. (11 ตุลาคม พ.ศ. 2539) The New Hacker's Dictionary (ฉบับที่ 3) สำนักพิมพ์เอ็มไอที หน้า 432. ISBN 978-0-262-68092-9. เก็บถาวรจากต้นฉบับเมื่อ 12 พฤศจิกายน 2555 . สืบค้นเมื่อ5 สิงหาคม 2555 .
  37. ^ "หน้าคนสำหรับผ้าสำลี (freebsd ส่วนที่ 1)" . ยูนิกซ์ . คอม 24 พฤษภาคม 2544 . สืบค้นเมื่อ15 กรกฎาคม 2014 .
  38. ^ เดล เนล บี.; วีมส์, ชิป (2014). การเขียนโปรแกรมและการแก้ปัญหาด้วย C++ (รุ่นที่ 6) เบอร์ลิงตัน รัฐแมสซาชูเซตส์: Jones & Bartlett Learning ISBN 978-1449694289. สพฐ . 894992484  .
  39. ^ แหล่งข้อมูล ของDr. Dobb สหรัฐอเมริกา: Miller Freeman, Inc. พฤศจิกายน–ธันวาคม 1995
  40. ^ "การใช้ภาษาซีสำหรับการเขียนโปรแกรม CGI " linuxjournal.com. 1 มีนาคม 2548 เก็บถาวรจากต้นฉบับเมื่อ 13 กุมภาพันธ์ 2553 . สืบค้นเมื่อ4 มกราคม 2010 .
  41. ^ Perkins, Luc (17 กันยายน 2556). "การพัฒนาเว็บใน C: บ้าหรือบ้าเหมือนจิ้งจอก?" . ปานกลาง .
  42. ^ เมตซ์, เคด. "เดนนิส ริตชี่: ไหล่ของสตีฟ จ็อบส์ ยืนหยัด" . แบบ มีสาย สืบค้นเมื่อ19 เมษายน 2022 .
  43. ^ "#pragma Directive ใน C/C++ " กี๊ กส์ฟอร์กีกส์ . 11 กันยายน 2561 . สืบค้นเมื่อ10 เมษายน 2022 .
  44. ^ "แพรกมาส" . อินเทล_ สืบค้นเมื่อ10 เมษายน 2022 .
  45. แมคมิลแลน, โรเบิร์ต (1 สิงหาคม 2013) " Java สูญเสีย Mojo หรือไม่" . แบบ มีสาย เก็บจากต้นฉบับเมื่อ 15 กุมภาพันธ์ 2017 . สืบค้นเมื่อ5 มีนาคม 2560 .
  46. โอรีแกน, เจอราร์ด (24 กันยายน 2558). Pillars of Computing: บทสรุปของบริษัทเทคโนโลยีที่สำคัญซึ่งคัดเลือกมาอย่างดี ISBN 978-3319214641. OCLC  922324121 .
  47. ^ เราช์แวร์เกอร์, ลอว์เรนซ์ (2004). ภาษาและคอมไพเลอร์สำหรับการคำนวณแบบคู่ขนาน : 16th international workshop, LCPC 2003, College Station, TX, USA, 2-4 ตุลาคม 2546 : แก้ไขเอกสาร สปริงเกอร์. ISBN 978-3540246442. OCLC  57965544 .
  48. สตรูสทรัป, บียาร์น (1993). "ประวัติของ C++: 1979-1991" (PDF ) เก็บถาวร(PDF)จากต้นฉบับเมื่อ 2 กุมภาพันธ์ 2019 . สืบค้นเมื่อ9 มิถุนายน 2554 .

ที่มา

อ่านเพิ่มเติม

ลิงค์ภายนอก