Fixed according to feedback
This commit is contained in:
+299
-149
@@ -28,86 +28,268 @@ Boehm garbage collector ตามลำดับ
|
||||
|
||||
=== การพัฒนาช่วงแรก
|
||||
|
||||
==== ภาษา B
|
||||
#h(9.75em) ที่มาของภาษา C มีความเชื่อมโยงอย่างใกล้ชิดกับการพัฒนาระบบปฏิบัติการ#jb Unix
|
||||
ซึ่งเดิมทีเขียนด้วยภาษาแอสเซมบลีบน PDP-7 โดย Dennis Ritchie และ Ken Thompson
|
||||
โดยนำแนวคิดหลายอย่างจากเพื่อนร่วมงานมาใช้ ในที่สุดพวกเขาก็ตัดสินใจย้ายระบบปฏิบัติการไปยัง PDP-11
|
||||
เวอร์ชัน Unix ดั้งเดิมบน PDP-11 ก็ได้รับการพัฒนาด้วยภาษาแอสเซมบลีเช่นกัน
|
||||
|
||||
==== ภาษา B ใหม่และ C รุ่นแรก
|
||||
=== ภาษา B
|
||||
|
||||
==== โครงสร้างและการเขียน Unix kernel ใหม่
|
||||
#h(13.5em) ทอมป์สันต้องการภาษาโปรแกรมสำหรับการพัฒนายูทิลิตี้สำหรับแพลตฟอร์มใหม่
|
||||
เขาพยายามเขียนคอมไพเลอร์ Fortran ก่อน
|
||||
แต่ในไม่ช้าเขาก็ล้มเลิกความคิดนั้นและสร้างเวอร์ชันย่อของภาษาโปรแกรมระบบ ที่พัฒนาขึ้นใหม่ชื่อ BCPL แทน
|
||||
คำอธิบายอย่างเป็นทางการของ BCPL ยังไม่พร้อมใช้งานในขณะนั้นและทอมป์สันได้แก้ไขไวยากรณ์ให้
|
||||
"กระชับ" น้อยลงและคล้ายกับ ALGOL ที่เรียบง่ายกว่า ที่เรียกว่า SMALGOL เขาเรียกผลลัพธ์ นี้ว่า B
|
||||
โดยอธิบายว่าเป็น#jb "ความหมายของ BCPL ที่มีไวยากรณ์ SMALGOL จำนวนมาก" เช่นเดียวกับ BCPL, B
|
||||
มีคอมไพเลอร์ บูตสแตรปเพื่ออำนวยความสะดวกในการพอร์ตไปยังเครื่องใหม่ในที่สุด
|
||||
มีการเขียนยูทิลิตี้เพียงไม่กี่ตัวใน B เพราะมันช้าเกินไปและไม่สามารถใช้ประโยชน์จากคุณสมบัติของ PDP-11
|
||||
เช่นการเข้าถึงที่อยู่ไบต์ได้
|
||||
|
||||
=== ภาษา B ใหม่และ C รุ่นแรก
|
||||
|
||||
#h(13.5em) ในปี พ.ศ. 2514 ริชชีเริ่มปรับปรุง B เพื่อใช้คุณสมบัติของ PDP-11 ที่ทรงพลังยิ่งขึ้น
|
||||
การเพิ่มเติมที่สำคัญคือประเภทข้อมูลอักขระ เขาเรียกสิ่งนี้ว่า New B (NB) ทอมป์สันเริ่มใช้ NB เพื่อเขียน
|
||||
เคอร์เนล Unix และข้อกำหนดของเขากำหนดทิศทางการพัฒนาภาษา
|
||||
|
||||
จนถึงปี 1972 มีการเพิ่มประเภทข้อมูลที่หลากหลายมากขึ้นให้กับภาษา NB ภาษา NB มีอาร์เรย์ของ int และ
|
||||
char และได้มีการเพิ่มพอยเตอร์ ความสามารถในการสร้างพอยเตอร์ไปยังประเภทอื่นๆ
|
||||
อาร์เรย์ของทุกประเภท และประเภทที่จะส่งคืนจากฟังก์ชัน
|
||||
อาร์เรย์ภายในนิพจน์ได้รับการปฏิบัติเสมือนเป็นพอยเตอร์ มีการเขียนคอมไพเลอร์ใหม่ และเปลี่ยนชื่อภาษาเป็น
|
||||
C
|
||||
|
||||
คอมไพเลอร์ C และยูทิลิตี้บางส่วนที่สร้างขึ้นด้วยคอมไพเลอร์นี้ถูกรวมอยู่ใน Unix เวอร์ชัน 2
|
||||
ซึ่งเรียกอีกอย่างว่า Research Unix
|
||||
|
||||
=== โครงสร้างและการเขียน Unix kernel ใหม่
|
||||
|
||||
#h(13.5em) ใน Unix เวอร์ชัน 4 ซึ่งวางจำหน่ายในเดือนพฤศจิกายน พ.ศ. 2516 เคอร์เนล ของ Unix
|
||||
ได้รับการเขียนใหม่อย่างกว้างขวางด้วยภาษา C ในเวลานั้น ภาษา C
|
||||
ได้รับคุณสมบัติที่ทรงพลังบางอย่างเช่นประเภท struct
|
||||
|
||||
ตัวประมวลผลล่วงหน้าได้รับการแนะนำประมาณปี 1973 ตามคำแนะนำของ Alan Snyder
|
||||
และยังเป็นการยอมรับถึงประโยชน์ของกลไกการรวมไฟล์ที่มีอยู่ใน BCPL และPL/I
|
||||
เวอร์ชันดั้งเดิมให้เฉพาะไฟล์ที่รวมไว้และการแทนที่สตริงแบบง่ายเท่านั้น `#include` รวม `#define`
|
||||
ถึงมาโครที่ไม่มีพารามิเตอร์ หลังจากนั้นไม่นาน ก็มีการขยายเพิ่มเติม โดยส่วนใหญ่โดย Mike Lesk
|
||||
และต่อมาโดย John Reiser เพื่อรวมมาโครที่มีอาร์กิวเมนต์และการคอมไพล์แบบมีเงื่อนไข
|
||||
|
||||
Unix เป็นหนึ่งในเคอร์เนลระบบปฏิบัติการแรกๆ
|
||||
ที่เขียนด้วยภาษาอื่นที่ไม่ใช่ภาษาแอสเซมบลีตัวอย่างก่อนหน้านี้ได้แก่ ระบบ Multics (ซึ่งเขียนด้วยภาษา
|
||||
PL/I ) และ Master Control Program (MCP) สำหรับ Burroughs B5000 (ซึ่งเขียนด้วยภาษา
|
||||
ALGOL ) ในปี 1961 ในช่วงปี 1977 Ritchie และ Stephen C. Johnson
|
||||
ได้ทำการเปลี่ยนแปลงเพิ่มเติมให้กับภาษาเพื่ออำนวยความสะดวกในการพกพาระบบปฏิบัติการUnix
|
||||
คอมไพเลอร์ Portable C ของ Johnson เป็นพื้นฐานสำหรับการใช้งาน C บนแพลตฟอร์มใหม่ๆ
|
||||
หลายแพลตฟอร์ม
|
||||
|
||||
=== K&R C
|
||||
|
||||
#h(9.75em) ในปี พ.ศ. 2521 Brian KernighanและDennis Ritchie ได้ตีพิมพ์หนังสือ The C
|
||||
Programming Language ฉบับพิมพ์ครั้งแรกหนังสือเล่มนี้รู้จักกันในชื่อย่อ K&R
|
||||
ตามชื่อย่อของผู้เขียนและทำหน้าที่เป็นข้อกำหนดที่ไม่เป็นทางการ ของภาษาเป็นเวลาหลายปีเวอร์ชันของภาษา
|
||||
C ที่อธิบายไว้ในหนังสือเล่มนี้มักเรียกกันว่า "K&R C" เนื่องจาก หนังสือเล่มนี้ได้รับการเผยแพร่ในปี พ.ศ.
|
||||
2521 จึงเรียกอีกอย่างว่า C78 หนังสือฉบับพิมพ์ครั้งที่สองครอบคลุมมาตรฐาน ANSI C ในภายหลัง
|
||||
ซึ่งจะกล่าวถึงต่อไป
|
||||
|
||||
K&R ได้เพิ่มฟีเจอร์ด้านภาษาหลายอย่าง:
|
||||
|
||||
+ ไลบรารีอินพุต/เอาต์พุตมาตรฐาน
|
||||
+ long int ประเภทข้อมูล
|
||||
+ unsigned int ประเภทข้อมูล
|
||||
+ ตัวดำเนินการกำหนดค่าแบบผสมในรูปแบบ =_op_ (เช่น `=-`) ถูกเปลี่ยนเป็นรูปแบบ _op_= (นั่นคือ
|
||||
`-=`)#jb เพื่อขจัดความกำกวมทางความหมายที่เกิดจากโครงสร้างเช่น `i=-10` ซึ่งถูกตีความว่า
|
||||
`i =- 10` (ลด `i` ลง 10) แทนที่จะเป็นความหมายที่ตั้งใจไว้ (ให้ `i` เป็น -10)
|
||||
|
||||
#h(9.75em) แม้หลังจากมีการเผยแพร่มาตรฐาน ANSI ปี 1989 แล้วก็ตาม เป็นเวลาหลายปีที่ K&R C
|
||||
ยังคงถูกพิจารณาว่าเป็น "ตัวหารร่วมที่ต่ำที่สุด" ที่โปรแกรมเมอร์ภาษา C
|
||||
ยึดถือเมื่อต้องการความสามารถในการพกพาได้สูงสุด
|
||||
เนื่องจากคอมไพเลอร์รุ่นเก่าจำนวนมากยังคงถูกใช้งานอยู่และเนื่องจากโค้ด K&R C
|
||||
ที่เขียนอย่างระมัดระวังก็สามารถเป็นไปตามมาตรฐาน C ได้เช่นกัน
|
||||
|
||||
แม้ว่า C เวอร์ชันต่อมาจะกำหนดให้ฟังก์ชันต้องมีการประกาศประเภทอย่างชัดเจนแต่ C เวอร์ชัน K&R
|
||||
กำหนดให้ฟังก์ชันที่ส่งคืนค่าประเภทอื่นที่ไม่ใช่ประเภท ที่กำหนดไว้เท่านั้น int ที่จะต้องประกาศก่อนใช้งาน
|
||||
ฟังก์ชันที่ใช้โดยไม่มีการประกาศล่วงหน้าจะถือว่าส่งคืนค่าประเภทที่กำหนด int ไว้
|
||||
|
||||
=== ANSI C และ ISO C
|
||||
|
||||
#h(9.75em) ในช่วงปลายทศวรรษ 1970 และ 1980 ภาษา C เวอร์ชันต่างๆ ถูกนำไปใช้งานใน
|
||||
คอมพิวเตอร์เมนเฟรมมินิคอมพิวเตอร์และไมโครคอมพิวเตอร์หลากหลายรุ่นรวมถึง IBM PC ด้วย
|
||||
เนื่องจากความนิยมของคอมพิวเตอร์ประเภทนี้เพิ่มขึ้นอย่างมาก
|
||||
|
||||
#h(9.75em) ในปี 1983 สถาบันมาตรฐานแห่งชาติอเมริกัน (ANSI) ได้จัดตั้งคณะกรรมการ#jb X3J11
|
||||
เพื่อกำหนดมาตรฐานของภาษา C X3J11 ใช้มาตรฐาน C ที่อิงตามการใช้งานบนระบบ Unix เป็นพื้นฐาน
|
||||
อย่างไรก็ตามส่วนที่ไม่สามารถพกพาได้ของไลบรารี C บน Unix ได้ถูกส่งต่อไปยังกลุ่มทำงาน IEEE 1003
|
||||
เพื่อใช้เป็นพื้นฐานสำหรับ มาตรฐาน POSIX ในปี 1988 ในปี 1989 มาตรฐาน C ได้รับการรับรองเป็น
|
||||
ANSI X3.159-1989 "ภาษาโปรแกรม C" เวอร์ชันนี้ของภาษามักถูกเรียกว่า ANSI C, Standard C
|
||||
หรือบางครั้งเรียกว่า C89
|
||||
|
||||
#h(9.75em) ในปี 1990 มาตรฐาน ANSI C (พร้อมการเปลี่ยนแปลงรูปแบบ)
|
||||
ได้รับการรับรองโดยองค์การมาตรฐานสากล (ISO) ในชื่อ ISO/IEC 9899:1990 ซึ่งบางครั้งเรียกว่า C90
|
||||
ดังนั้น คำว่า "C89" และ "C90" จึงหมายถึงภาษาโปรแกรมเดียวกัน
|
||||
|
||||
#h(9.75em) เช่นเดียวกับองค์กรมาตรฐานแห่งชาติอื่นๆ ANSI ไม่ได้พัฒนามาตรฐาน C ด้วยตนเองอีกต่อไป
|
||||
แต่จะอ้างอิงถึงมาตรฐาน C สากล ซึ่งดูแลโดยคณะทำงาน ISO/IEC JTC1/SC22 /WG14
|
||||
การนำมาตรฐานสากลฉบับปรับปรุงมาใช้ในระดับประเทศมักเกิดขึ้นภายในหนึ่งปีหลังจากที่ ISO
|
||||
เผยแพร่มาตรฐานดังกล่าว
|
||||
|
||||
#h(9.75em) หนึ่งในเป้าหมายของกระบวนการกำหนดมาตรฐานภาษา C คือการสร้างซูเปอร์เซ็ตของ K&R C
|
||||
โดยรวมเอาคุณสมบัติที่ไม่เป็นทางการหลายอย่างที่ถูกนำมาใช้ในภายหลัง
|
||||
คณะกรรมการมาตรฐานยังได้เพิ่มคุณสมบัติเพิ่มเติมอีกหลายอย่างเช่นต้นแบบฟังก์ชัน (ยืมมาจาก C++),
|
||||
voidพอยเตอร์, การรองรับชุดอักขระและภาษาท้องถิ่นระหว่างประเทศ และการปรับปรุงพรีโปรเซสเซอร์
|
||||
แม้ว่าไวยากรณ์สำหรับการประกาศพารามิเตอร์จะได้รับการปรับปรุงให้รวมรูปแบบที่ใช้ใน C++
|
||||
แต่ก็ยังคงอนุญาตให้ใช้อินเทอร์เฟซ K&R เพื่อความเข้ากันได้กับซอร์สโค้ดที่มีอยู่
|
||||
|
||||
#h(9.75em) C89 ได้รับการสนับสนุนจากคอมไพเลอร์ C ในปัจจุบัน และโค้ด C สมัยใหม่ส่วนใหญ่ก็ใช้ C89
|
||||
เป็นพื้นฐานโปรแกรมใดๆ ที่เขียนด้วยภาษา C มาตรฐานเท่านั้น และไม่มีข้อสมมติฐานใดๆ ที่ขึ้นอยู่กับฮาร์ดแวร์
|
||||
จะทำงานได้อย่างถูกต้องบนแพลตฟอร์มใดๆ ที่มีการใช้งาน C ที่สอดคล้องกับมาตรฐาน
|
||||
ภายในขีดจำกัดของทรัพยากร หากไม่ระมัดระวัง
|
||||
โปรแกรมอาจคอมไพล์ได้เฉพาะบนแพลตฟอร์มใดแพลตฟอร์มหนึ่ง หรือด้วยคอมไพเลอร์เฉพาะเท่านั้น
|
||||
ตัวอย่างเช่น เนื่องจากการใช้ไลบรารีที่ไม่เป็นมาตรฐาน เช่น ไลบรารี GUI
|
||||
หรือการพึ่งพาคุณลักษณะเฉพาะของคอมไพเลอร์หรือแพลตฟอร์ม เช่น ขนาดที่แน่นอนของชนิดข้อมูลและลำดับไบต์
|
||||
|
||||
#h(9.75em)
|
||||
ในกรณีที่โค้ดต้องสามารถคอมไพล์ได้ทั้งโดยคอมไพเลอร์ที่สอดคล้องกับมาตรฐานหรือคอมไพเลอร์ที่ใช้ C แบบ
|
||||
K&R นั้น `__STDC__` สามารถใช้มาโครเพื่อแบ่งโค้ดออกเป็นส่วนมาตรฐานและส่วน K&R
|
||||
เพื่อป้องกันการใช้คุณสมบัติที่มีเฉพาะใน C มาตรฐานบนคอมไพเลอร์ที่ใช้ C แบบ K&R
|
||||
|
||||
#h(9.75em) หลังจากกระบวนการกำหนดมาตรฐาน ANSI/ISO ข้อกำหนดภาษา C
|
||||
ยังคงค่อนข้างคงที่เป็นเวลาหลายปี ในปี 1995 มีการเผยแพร่การแก้ไขมาตรฐานฉบับที่ 1 ของมาตรฐาน C ปี
|
||||
1990 (ISO/IEC 9899/AMD1:1995 ซึ่งเรียกกันอย่างไม่เป็นทางการว่า C95)
|
||||
เพื่อแก้ไขรายละเอียดบางประการและเพิ่มการสนับสนุนชุดอักขระสากลที่ครอบคลุมมากขึ้น
|
||||
|
||||
=== C99
|
||||
|
||||
#h(9.75em) มาตรฐาน C ได้รับการแก้ไขเพิ่มเติมในช่วงปลายทศวรรษ 1990 ส่งผลให้มีการตีพิมพ์
|
||||
ISO/IEC 9899:1999 ในปี 1999 ซึ่งโดยทั่วไปเรียกว่า "C99" ต่อมาได้มีการแก้ไขเพิ่มเติมอีกสามครั้งโดย
|
||||
Technical Corrigenda
|
||||
|
||||
#h(9.75em) C99 ได้นำเสนอคุณสมบัติใหม่หลายประการรวมถึงฟังก์ชันอินไลน์ชนิดข้อมูลใหม่หลายชนิด(รวมถึง
|
||||
long long intชนิด ข้อมูล complex ที่ใช้แทนจำนวนเชิงซ้อน)
|
||||
อาร์เรย์ที่มีความยาวแปรผันได้และสมาชิกอาร์เรย์ที่ยืดหยุ่นการสนับสนุนที่ดีขึ้นสำหรับเลขทศลอย IEEE 754
|
||||
การสนับสนุนมาโครแบบแปรผัน (มาโครที่มีจำนวนอาร์กิวเมนต์ แปรผันได้)
|
||||
และการสนับสนุนความคิดเห็นแบบบรรทัดเดียวที่ขึ้นต้นด้วย `@` `//` เช่นเดียวกับใน BCPL หรือ C++
|
||||
คุณสมบัติเหล่านี้หลายอย่างได้ถูกนำไปใช้เป็นส่วนขยายในคอมไพเลอร์ C หลายตัวแล้ว
|
||||
|
||||
#h(9.75em) โดยส่วนใหญ่แล้ว C99 สามารถใช้งานร่วมกับ C90 ได้ แต่มีความเข้มงวดมากกว่าในบางด้าน
|
||||
โดยเฉพาะอย่างยิ่ง การประกาศที่ไม่มีตัวระบุประเภทจะไม่ถือว่ามีintการกำหนดโดยปริยายอีกต่อไป
|
||||
มีการกำหนดมาโครมาตรฐาน `__STDC_VERSION__` พร้อมค่า `199901L` เพื่อระบุว่ามีการสนับสนุน C99
|
||||
คอม ไพเลอร์ C อื่นๆ เช่น GCC, Solaris Studio และคอมไพเลอร์ C อื่นๆ
|
||||
ในปัจจุบันรองรับคุณสมบัติใหม่หลายอย่างหรือทั้งหมดของ C99 อย่างไรก็ตาม คอมไพเลอร์ C ใน Microsoft
|
||||
Visual C++ ใช้มาตรฐาน C89 และส่วนต่างๆ ของ C99 ที่จำเป็นสำหรับการใช้งานร่วมกับ C++11
|
||||
|
||||
#h(9.75em) นอกจากนี้ มาตรฐาน C99 ยังกำหนดให้รองรับตัวระบุที่ใช้ Unicode
|
||||
ในรูปแบบของอักขระพิเศษ (เช่น `\u0040` หรือ `\U0001f431`) และแนะนำให้รองรับชื่อ Unicode
|
||||
ดิบด้วย
|
||||
|
||||
=== C11
|
||||
|
||||
#h(9.75em) งานปรับปรุงมาตรฐาน C ฉบับใหม่เริ่มขึ้นในปี 2550 โดยเรียกกันอย่างไม่เป็นทางการว่า
|
||||
"C1X" จนกระทั่งมีการประกาศใช้มาตรฐาน ISO/IEC 9899:2011 อย่างเป็นทางการในวันที่ 8 ธันวาคม
|
||||
2554 คณะกรรมการมาตรฐาน C ได้กำหนดแนวทางเพื่อจำกัดการนำคุณสมบัติใหม่ๆ
|
||||
ที่ยังไม่ได้รับการทดสอบโดยระบบที่มีอยู่มาใช้
|
||||
|
||||
#h(9.75em) มาตรฐาน C11 เพิ่มคุณสมบัติใหม่มากมายให้กับภาษา C และไลบรารี
|
||||
รวมถึงมาโครแบบเจเนริกชนิดโครงสร้างนิรนามการสนับสนุน Unicode ที่ดีขึ้น
|
||||
การดำเนินการอะตอมิกการทำงานแบบมัลติเธรดและฟังก์ชันตรวจสอบขอบเขต
|
||||
นอกจากนี้ยังทำให้บางส่วนของไลบรารี C99 ที่มีอยู่เป็นตัวเลือก และปรับปรุงความเข้ากันได้กับ C++
|
||||
มาโครมาตรฐาน `__STDC_VERSION__` ถูกกำหนดไว้เพื่อ `201112L` ระบุว่ามีการสนับสนุน C11 แล้ว
|
||||
|
||||
=== C17
|
||||
|
||||
#h(9.75em) C17 เป็นชื่อเรียกอย่างไม่เป็นทางการของ ISO/IEC 9899:2018
|
||||
ซึ่งเป็นมาตรฐานสำหรับภาษาโปรแกรม C ที่เผยแพร่ในเดือนมิถุนายน 2018
|
||||
มาตรฐานนี้ไม่ได้เพิ่มคุณสมบัติใหม่ใดๆ ให้กับภาษา แต่เป็นการแก้ไขทางเทคนิคและการชี้แจงข้อบกพร่องใน
|
||||
C11 เท่านั้น มาโครมาตรฐาน `__STDC_VERSION__` ถูกกำหนดขึ้นเพื่อ `201710L` ระบุว่ามีการรองรับ
|
||||
C17 แล้ว
|
||||
|
||||
=== C23
|
||||
|
||||
#h(9.75em) C23 เป็นชื่อเรียกอย่างไม่เป็นทางการของการแก้ไขมาตรฐานภาษา C หลักในปัจจุบัน
|
||||
ซึ่งในระหว่างการพัฒนาส่วนใหญ่เรียกว่า "C2X" โดยสร้างขึ้นจากเวอร์ชันก่อนหน้า และแนะนำคุณสมบัติใหม่
|
||||
เช่น คำหลักใหม่ ความหมายเพิ่มเติมสำหรับเพื่อ `auto`
|
||||
ให้มีการอนุมานประเภทเมื่อประกาศตัวแปรประเภทใหม่รวมถึง `nullptr_t` และ `_BitInt` (N)
|
||||
และการขยายไลบรารีมาตรฐาน
|
||||
|
||||
C23 ได้รับการเผยแพร่ในเดือนตุลาคม 2024 ในชื่อ ISO/IEC 9899:2024 มาโครมาตรฐาน
|
||||
`__STDC_VERSION__` ถูกกำหนดไว้ `202311L` เพื่อระบุว่ามีการสนับสนุน C23
|
||||
|
||||
=== C2Y
|
||||
|
||||
#h(9.75em) C2Y เป็นชื่อเรียกอย่างไม่เป็นทางการของการแก้ไขมาตรฐานภาษา C ครั้งใหญ่ถัดไป หลังจาก
|
||||
C23 (C2X) ซึ่งคาดว่าจะออกในช่วงปลายทศวรรษ 2020 ดังนั้นจึงมีเลข '2' ใน "C2Y" ร่างฉบับแรกของ
|
||||
C2Y ได้รับการเผยแพร่ในเดือนกุมภาพันธ์ 2024 ในชื่อ N3220 โดยกลุ่มทำงาน ISO/IEC JTC1/SC22
|
||||
/WG14
|
||||
|
||||
=== Embedded C
|
||||
|
||||
#h(9.75em) ในอดีตการเขียนโปรแกรม C
|
||||
สำหรับระบบฝังตัวจำเป็นต้องใช้ส่วนขยายที่ไม่เป็นมาตรฐานของภาษา C เพื่อรองรับคุณสมบัติพิเศษ
|
||||
เช่นการคำนวณเลขทศนิยมคงที่
|
||||
ธนาคารหน่วยความจำหลายชุดที่แตกต่างกันและการดำเนินการอินพุต/เอาต์พุตพื้นฐาน
|
||||
|
||||
#h(9.75em) ในปี 2551 คณะกรรมการมาตรฐาน C ได้เผยแพร่รายงานทางเทคนิคที่ขยายภาษา C
|
||||
เพื่อแก้ไขปัญหาเหล่านี้โดยการจัดหามาตรฐานทั่วไปสำหรับการใช้งานทั้งหมดให้ปฏิบัติตาม
|
||||
ซึ่งรวมถึงคุณสมบัติหลายอย่างที่ไม่มีในภาษา C ปกติ เช่น การคำนวณเลขทศนิยมคงที่
|
||||
พื้นที่แอดเดรสแบบมีชื่อและการกำหนดแอดเดรสฮาร์ดแวร์ I/O พื้นฐาน
|
||||
|
||||
== ตัวแปร (Variables)
|
||||
|
||||
#i ตัวแปรในภาษา C เบื้องต้นแล้วประกอบไปด้วยประเภทของข้อมูล และชื่อตัวแปร
|
||||
#i ตัวแปรในภาษา C เบื้องต้นแล้วประกอบไปด้วยประเภทของข้อมูลและชื่อตัวแปร
|
||||
โดยที่ชื่อตัวแปรนั้นสามารถเป็นรายการที่ถูกแบ่งด้วยเครื่องหมายจุลภาคได้ด้วยเช่นกัน ตัวอย่างคือ
|
||||
|
||||
```c
|
||||
int data;
|
||||
float a, b, c;
|
||||
```
|
||||
#afigure(
|
||||
```c
|
||||
int data;
|
||||
float a, b, c;
|
||||
```,
|
||||
kind: image,
|
||||
caption: [ตัวอย่างการประกาศตัวแปรในภาษา C],
|
||||
)
|
||||
|
||||
== ประเภทข้อมูล (Data Types)
|
||||
|
||||
#i ข้อมูลที่เกี่ยวข้องกับตัวเลขมักมีประเภท *unsigned* และ *signed* โดยความแตกต่างหากอธิบายสั้น
|
||||
#h(6em) ข้อมูลที่เกี่ยวข้องกับตัวเลขมักมีประเภท unsigned และ signed โดยความแตกต่างหากอธิบายสั้น
|
||||
ๆ คือ
|
||||
|
||||
- *Signed (มีเครื่องหมาย):* ตัวเลขที่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ -128 ถึง 127
|
||||
- *Unsigned (ไม่มีเครื่องหมาย):* ตัวเลขที่ไม่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ 0 ถึง 255
|
||||
#[
|
||||
#set enum(indent: 6em)
|
||||
+ Signed (มีเครื่องหมาย): ตัวเลขที่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ -128 ถึง 127
|
||||
+ Unsigned (ไม่มีเครื่องหมาย): ตัวเลขที่ไม่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ 0 ถึง 255
|
||||
]
|
||||
|
||||
#i จะสังเกตได้ว่า ข้อมูลประเภท unsigned นั้นสามารถเก็บตัวเลขบวกได้จำนวนมากกว่า คือสูงสุดที่ 255
|
||||
แต่หากนำค่าสัมบูรณ์ (absolute value) ของระยะข้อมูลแบบ signed มาบวกกัน เช่น\
|
||||
#h(6em) จะสังเกตได้ว่า ข้อมูลประเภท unsigned นั้นสามารถเก็บตัวเลขบวกได้จำนวนมากกว่า คือสูงสุดที่
|
||||
255 แต่หากนำค่าสัมบูรณ์ (absolute value) ของระยะข้อมูลแบบ signed มาบวกกัน เช่น\
|
||||
#math.equation($|-128| + |127|$, alt: "ค่าสัมบูรณ์ของ -128 บวกค่าสัมบูรณ์ของ 127")
|
||||
จะพบว่าได้ค่า 255 หมายความว่า จริง ๆ แล้วข้อมูลประเภท signed สามารถเก็บข้อมูลได้ 255
|
||||
ตัวเลขเช่นกัน เพียงแต่ว่าครึ่งหนึ่งของตัวเลขที่สามารถเก็บได้เป็นตัวเลขติดลบ
|
||||
|
||||
*หมายเหตุ:* เลขคณิตจำนวนเต็มมีนิยามแตกต่างกันสำหรับชนิดจำนวนเต็มแบบ signed และ unsigned
|
||||
โปรดดูตัวดำเนินการเลขคณิต โดยเฉพาะอย่างยิ่งการโอเวอร์โฟลว์จำนวนเต็ม
|
||||
#h(6em) ดังนั้นโปรดจำไว้ว่า เลขคณิตจำนวนเต็มมีนิยามแตกต่างกันสำหรับชนิดจำนวนเต็มแบบ signed และ
|
||||
unsigned โปรดดูตัวดำเนินการเลขคณิต โดยเฉพาะอย่างยิ่งการโอเวอร์โฟลว์จำนวนเต็ม
|
||||
|
||||
=== ประเภทบูลีน (Boolean)
|
||||
|
||||
*หมายเหตุ:* ประเภทบูลีนนั้นถูกนำเสนอครั้งแรกในมาตรฐาน C99
|
||||
ประเภทบูลีนนั้นถูกนำเสนอครั้งแรกในมาตรฐาน C99 โดยการกล่าวถึงประเภทข้อมูลบูลีนนั้น ในประวัติของภาษา C แล้วมีสองแบบ
|
||||
|
||||
โดยการกล่าวถึงประเภทข้อมูลบูลีนนั้น ในประวัติของภาษา C แล้วมีสองแบบ
|
||||
|
||||
- `_Bool` (และมีมาโคร `bool`): จนถึงมาตรฐาน C23
|
||||
- `bool` (ที่ไม่ใช่แค่มาโคร): มีตั้งแต่มาตรฐาน C23
|
||||
+ `_Bool` (และมีมาโคร `bool`): จนถึงมาตรฐาน C23
|
||||
+ `bool` (ที่ไม่ใช่แค่มาโคร): มีตั้งแต่มาตรฐาน C23
|
||||
|
||||
=== ประเภทจำนวนเต็ม (Integer)
|
||||
|
||||
- `short int` (หรืออีกชื่อหนึ่งคือ `short` และสามารถใช้คีย์เวิร์ด `signed` ได้)
|
||||
- `unsigned short int` (หรือ `unsigned short`)
|
||||
- `int` (หรือ `signed int`) \
|
||||
+ `short int` (หรืออีกชื่อหนึ่งคือ `short` และสามารถใช้คีย์เวิร์ด `signed` ได้)
|
||||
+ `unsigned short int` (หรือ `unsigned short`)
|
||||
+ `int` (หรือ `signed int`) \
|
||||
คือประเภทข้อมูลตัวเลขที่ปกติที่สุด และจะถูกการันตีว่าจะมีขนาดขั้นต่ำ 16 บิตเสมอ
|
||||
โดยระบบทั่วไปส่วนใหญ่ในปัจจุบันจะเป็น 32 บิต
|
||||
- `unsigned int` (หรือเพียงแค่ `unsigned`): คือประเภท `int` ในแบบ `unsigned`, มี
|
||||
+ `unsigned int` (หรือเพียงแค่ `unsigned`): คือประเภท `int` ในแบบ `unsigned`, มี
|
||||
modulo arithmetic, และเหมาะสมสำหรับการเปลี่ยนแปลงบิต
|
||||
- `long int` (หรือ `long`)
|
||||
- `unsigned long int` (หรือ `unsigned long`)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
- มีเพิ่มตั้งแต่ C99:
|
||||
- `long long int` (หรือ `long long`)
|
||||
- `unsigned long long int` (หรือ `unsigned long long`)
|
||||
- มีเพิ่มตั้งแต่ C23:
|
||||
- `_BitInt(n)` (หรือ `signed _BitInt(n)`): ประเภทข้อมูล signed แบบมีขนาดชัดเจน โดย
|
||||
+ `long int` (หรือ `long`)
|
||||
+ `unsigned long int` (หรือ `unsigned long`)
|
||||
+ มีเพิ่มตั้งแต่ C99:
|
||||
+ `long long int` (หรือ `long long`)
|
||||
+ `unsigned long long int` (หรือ `unsigned long long`)
|
||||
+ มีเพิ่มตั้งแต่ C23:
|
||||
+ `_BitInt(n)` (หรือ `signed _BitInt(n)`): ประเภทข้อมูล signed แบบมีขนาดชัดเจน โดย
|
||||
n แทนด้วยจำนวนบิต (รวมถึงบิตเครื่องหมาย และ n จะต้องไม่มากกว่า `BITINT_MAXWIDTH`
|
||||
จากไฟล์ `<limits.h>`)
|
||||
- `unsigned _BitInt(n)`: เหมือนข้างต้น เพียงแค่เป็นประเภท unsigned
|
||||
+ `unsigned _BitInt(n)`: เหมือนข้างต้น เพียงแค่เป็นประเภท unsigned
|
||||
(และไม่มีบิตเครื่องหมาย)
|
||||
|
||||
และเหมือนประเภทข้อมูลอื่น ๆ คุณสามารถเรียงคีย์เวิร์ดแบบใดก็ได้ เช่น `unsigned long long int`
|
||||
@@ -221,74 +403,54 @@ float a, b, c;
|
||||
caption: [ขนาดของข้อมูลเป็นบิต (ต่อ)],
|
||||
)
|
||||
|
||||
และนอกจากค่าบิตขั้นต่ำ มาตรฐาน C นั้นการันตีว่า:
|
||||
|
||||
#i ```c 1``` == ```c sizeof(char)``` #sym.lt.eq ```c sizeof(short)``` #sym.lt.eq
|
||||
```c sizeof(int)``` #sym.lt.eq ```c sizeof(long)``` #sym.lt.eq
|
||||
```c sizeof(long long)```
|
||||
|
||||
*หมายเหตุ:* เงื่อนไขนี้อนุญาตกรณีสุดขีดที่ทุกประเภทมีขนาด 64 บิตและ `sizeof` คืนค่า `1`
|
||||
สำหรับทุกประเภท
|
||||
|
||||
==== รูปแบบข้อมูล (data model)
|
||||
|
||||
#i รูปแบบข้อมูล หรือ data model คือรูปแบบการเก็บข้อมูลของโปรแกรมซึ่งเป็นสิ่งที่กำหนดขนาดของตัวแปร
|
||||
#h(13.5em) รูปแบบข้อมูล หรือ data model
|
||||
คือรูปแบบการเก็บข้อมูลของโปรแกรมซึ่งเป็นสิ่งที่กำหนดขนาดของตัวแปร
|
||||
โดยรูปแบบข้อมูลนั้นจะถูกกำหนดโดยแพลตฟอร์มเป้าหมาย
|
||||
ซึ่งมีหน่วยประมวลผลและระบบปฏิบัติการเป็นปัจจัยหลัก โดยตามตารางในหัวข้อก่อนหน้า หลัก ๆ
|
||||
แล้วมีรูปแบบข้อมูลอยู่ 4 รูปแบบ คือ LP32, ILP32, LLP64, และ LP64 ซึ่งหากต้องการหาความหาย L
|
||||
หมายถึง Long, P หมายถึง Pointer, และ I หมายถึง Integer (จำนวนเต็ม) แล้วตามด้วยเลขบิต
|
||||
ดังนั้น สรุปแล้วจึงจะมีความหมายดังนี้
|
||||
|
||||
ระบบ 32 บิต:
|
||||
- LP32 หรือ 2/4/4: `long` และ Pointer มีขนาด 32 บิต
|
||||
- Win16 API
|
||||
- ILP32 หรือ 4/4/4: `int`, `long`, และ Pointer มีขนาด 32 บิต
|
||||
- Win32 API
|
||||
- ระบบ Unix และเสมือน Unix (Linux, Mac OS X)
|
||||
|
||||
ระบบ 64 บิต:
|
||||
- LLP64 หรือ 4/4/8: `long long` และ Pointer มีขนาด 64 บิต
|
||||
- Win64 API
|
||||
- LP64 หรือ 4/8/8: `long` และ Pointer มีขนาด 64 บิต
|
||||
- ระบบ Unix และเสมือน Unix (Linux, Mac OS X)
|
||||
|
||||
#i รูปแบบอื่น ๆ นั้นหาได้ยาก ตัวอย่างเช่น ILP64 (8/8/8: `int`, `long`, และ Pointer ขนาด
|
||||
64 บิต) ที่มีการใช้งานแค่ในระบบ Unix 64 บิตช่วงเริ่มต้น (เช่น Unicos บน Cray)
|
||||
|
||||
และโปรดจำไว้ว่า ตัวเลขที่มีขนาดแน่นอนนั้นมีให้ใช้งานใน `<stdint.h>` ตั้งแต่ C99
|
||||
|
||||
=== ประเภทจำนวนทศนิยมจริง (Real floating types)
|
||||
|
||||
ภาษา C นั้นมีประเภทข้อมูลสำหรับแทนตัวเลขทศนิยมจริง 3 (หรือ 6 ตั้งแต่ C23) ประเภท
|
||||
#h(9.75em) ภาษา C นั้นมีประเภทข้อมูลสำหรับแทนตัวเลขทศนิยมจริง 3 (หรือ 6 ตั้งแต่ C23) ประเภท
|
||||
|
||||
- `float`: จำนวนทศนิยมความแม่นยำเดี่ยว ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary32 หากรองรับ
|
||||
- `double`: จำนวนทศนิยมความแม่นยำสองเท่า ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary64
|
||||
+ `float`: จำนวนทศนิยมความแม่นยำเดี่ยว ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary32 หากรองรับ
|
||||
+ `double`: จำนวนทศนิยมความแม่นยำสองเท่า ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary64
|
||||
หากรองรับ
|
||||
- `long double`: จำนวนทศนิยมความแม่นยำเพิ่มเติม ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary128
|
||||
+ `long double`: จำนวนทศนิยมความแม่นยำเพิ่มเติม ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary128
|
||||
หากรองรับ มิฉะนั้นจะตรงกับ IEEE-754 binary64-extended หากรองรับ
|
||||
มิฉะนั้นจะตรงกับรูปแบบจำนวนทศนิยมที่ไม่ตรงกับมาตรฐาน IEEE-754
|
||||
รูปแบบใดก็ได้ตราบใดที่มีความแม่นยำกว่า binary64 และระยะข้อมูลนั้นอย่างน้อยก็ต้องดีเท่า binary64
|
||||
และหากไม่รองรับทั้งหมดนั้น จะตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary64
|
||||
- รูปแบบ binary128 นั้นถูกใช้โดยระบบ HP-UX, SPARC, MIPS, ARM64, และ z/OS บางระบบ
|
||||
- รูปแบบ IEEE-754 binary64-extended ที่รู้จักกันอย่างแพร่หลายที่สุดคือรูปแบบความแม่นยำเพิ่มเติม
|
||||
+ รูปแบบ binary128 นั้นถูกใช้โดยระบบ HP-UX, SPARC, MIPS, ARM64, และ z/OS บางระบบ
|
||||
+ รูปแบบ IEEE-754 binary64-extended ที่รู้จักกันอย่างแพร่หลายที่สุดคือรูปแบบความแม่นยำเพิ่มเติม
|
||||
80 บิต x87 ซึ่งถูกใช้โดยสถาปัตยกรรม x86 และ x86-64 บางระบบ (การยกเว้นที่ควรพูดถึงคือ
|
||||
MSVC ที่กำหนดให้ `long double` อยู่ในรูปแบบเดียวกันกับ `double`, เช่น binary64)
|
||||
|
||||
เมื่อใช้มาตรฐาน C ตั้งแต่ C23 เป็นต้นไปและหากแพลตฟอร์มของคุณใช้งานคอนแสตนต์มาโคร
|
||||
`__STDC_IEC_60559_DFP__` ข้อมูลประเภทตัวเลขทศนิยมดังต่อไปนี้จะถูกรองรับด้วย:
|
||||
|
||||
- `_Decimal32`: แทนรูปแบบมาตรฐาน IEEE-754 decimal32
|
||||
- `_Decimal64`: แทนรูปแบบมาตรฐาน IEEE-754 decimal64
|
||||
- `_Decimal128`: แทนรูปแบบมาตรฐาน IEEE-754 decimal128
|
||||
#[
|
||||
#set enum(indent:9.75em)
|
||||
+ `_Decimal32`: แทนรูปแบบมาตรฐาน IEEE-754 decimal32
|
||||
+ `_Decimal64`: แทนรูปแบบมาตรฐาน IEEE-754 decimal64
|
||||
+ `_Decimal128`: แทนรูปแบบมาตรฐาน IEEE-754 decimal128
|
||||
]
|
||||
|
||||
มิฉะนั้น ประเภทตัวเลขทศนิยมเพิ่มเติมเหล่านี้จะไม่ถูกรองรับ
|
||||
|
||||
ข้อมูลประเภททศนิยมอาจรองรับค่าพิเศษเพิ่มเติมได้แก่
|
||||
|
||||
- อนันต์ (Infinity, ทั้งบวกและลบ)
|
||||
- ศูนย์ติดลบ, `-0.0` โดยมีค่าเท่ากับศูยน์ที่ติดบวก แต่อาจมีความหมายในบางสมการ เช่น
|
||||
#[
|
||||
#set enum(indent: 9.75em)
|
||||
+ อนันต์ (Infinity, ทั้งบวกและลบ)
|
||||
+ ศูนย์ติดลบ, `-0.0` โดยมีค่าเท่ากับศูยน์ที่ติดบวก แต่อาจมีความหมายในบางสมการ เช่น
|
||||
`1.0 / 0.0 == INFINITY` แต่ `1.0 / -0.0 == -INFINITY`
|
||||
- ไม่ใช่ตัวเลข (not-a-number; NaN) ซึ่งไม่เท่ากับอะไรเลย (รวมถึงตัวมันเอง)
|
||||
+ ไม่ใช่ตัวเลข (not-a-number; NaN) ซึ่งไม่เท่ากับอะไรเลย (รวมถึงตัวมันเอง)
|
||||
]
|
||||
|
||||
ทศนิยมจำนวนจริงสามารถถูกใช้กับตัวดำเนินการทางคณิตศาสตร์ได้ *+ - / \**
|
||||
และฟังก์ชันทางคณิตศาสตร์จาก `<math.h>`
|
||||
@@ -297,22 +459,15 @@ float a, b, c;
|
||||
|
||||
=== ประเภทจำนวนทศนิยมซับซ้อน (Complex floating types)
|
||||
|
||||
#i ประเภทข้อมูลจำนวนทศนิยมซับซ้อนนั้นเป็นประเภทที่แทนตัวเลขเชิงซ้อน (complex number) นั้นคือ
|
||||
ตัวเลขที่สามารถถูกเขียนแทนเป็นผลรวมของจำนวนจริงและจำนวนจริงที่คูณด้วยจำนวนจินตภาพ:
|
||||
#math.equation($a + b i$, alt: "a บวก b i")
|
||||
#h(9.75em) ประเภทข้อมูลจำนวนทศนิยมซับซ้อนนั้นเป็นประเภทที่แทนตัวเลขเชิงซ้อน (complex number)
|
||||
นั้นคือ ตัวเลขที่สามารถถูกเขียนแทนเป็นผลรวมของจำนวนจริงและจำนวนจริงที่คูณด้วยจำนวนจินตภาพ (a +
|
||||
bi) โดยประเภทจำนวนเชิงซ้อนมีอยู่สามประเภท ได้แก่
|
||||
|
||||
ประเภทจำนวนเชิงซ้อนมีอยู่สามประเภท ได้แก่
|
||||
|
||||
- ```c float _Complex``` (และสามารถใช้ ```c float complex``` ได้เช่นกันหากนำเข้า
|
||||
+ `float _Complex` (และสามารถใช้ `float complex` ได้เช่นกันหากนำเข้า `<complex.h>`)
|
||||
+ `double _Complex` (และสามารถใช้ `double complex` ได้เช่นกันหากนำเข้า `<complex.h>`)
|
||||
+ `long double _Complex` (และสามารถใช้ `long double complex` ได้เช่นกันหากนำเข้า
|
||||
`<complex.h>`)
|
||||
- ```c double _Complex``` (และสามารถใช้ ```c double complex``` ได้เช่นกันหากนำเข้า
|
||||
`<complex.h>`)
|
||||
- ```c long double _Complex``` (และสามารถใช้ ```c long double complex```
|
||||
ได้เช่นกันหากนำเข้า `<complex.h>`)
|
||||
|
||||
*หมายเหตุ:* เหมือนกับประเภทอื่น ๆ สามารถพิมพ์คีย์เวิร์ดในลำดับใดก็ได้
|
||||
```c long double complex```, ```c complex long double``` และแม้แต่
|
||||
```c double complex long``` นั้นคือประเภทข้อมูลเดียวกัน
|
||||
|
||||
=== ประเภทจำนวนทศนิยมจินตภาพ (Imaginary floating types)
|
||||
|
||||
@@ -324,52 +479,47 @@ float a, b, c;
|
||||
|
||||
ประเภทจำนวนเชิงซ้อนมีอยู่สามประเภท ได้แก่
|
||||
|
||||
- ```c float _Imaginary``` (และสามารถใช้ ```c float imaginary``` ได้เช่นกันหากนำเข้า
|
||||
+ `float _Imaginary` (และสามารถใช้ `float imaginary` ได้เช่นกันหากนำเข้า
|
||||
`<complex.h>`)
|
||||
+ `double _Imaginary` (และสามารถใช้ `double imaginary` ได้เช่นกันหากนำเข้า
|
||||
`<complex.h>`)
|
||||
+ `long double _Imaginary` (และสามารถใช้ `long double imaginary` ได้เช่นกันหากนำเข้า
|
||||
`<complex.h>`)
|
||||
- ```c double _Imaginary``` (และสามารถใช้ ```c double imaginary```
|
||||
ได้เช่นกันหากนำเข้า `<complex.h>`)
|
||||
- ```c long double _Imaginary``` (และสามารถใช้ ```c long double imaginary```
|
||||
ได้เช่นกันหากนำเข้า `<complex.h>`)
|
||||
|
||||
*หมายเหตุ:* เหมือนกับประเภทอื่น ๆ สามารถพิมพ์คีย์เวิร์ดในลำดับใดก็ได้
|
||||
```c long double imaginary```, ```c imaginary long double``` และแม้แต่
|
||||
```c double imaginary long``` นั้นคือประเภทข้อมูลเดียวกัน
|
||||
|
||||
=== ประเภทตัวอักษร (Character)
|
||||
|
||||
- `signed char`: ประเภทสำหรับตัวอักษรแบบ signed
|
||||
- `unsigned char`: ประเภทสำหรับตัวอักษรแบบ unsigned
|
||||
- `char`: ประเภทสำหรับตัวอักษรแบบไม่ระบุระยะข้อมูล ซึ่งสามารถเท่ากับ `signed char` หรือ
|
||||
+ `signed char`: ประเภทสำหรับตัวอักษรแบบ signed
|
||||
+ `unsigned char`: ประเภทสำหรับตัวอักษรแบบ unsigned
|
||||
+ `char`: ประเภทสำหรับตัวอักษรแบบไม่ระบุระยะข้อมูล ซึ่งสามารถเท่ากับ `signed char` หรือ
|
||||
`unsigned char` ก็ได้ขึ้นอยู่กับแพลตฟอร์มและคอมไพเลอร์ แต่อย่างไรก็ตาม `char`
|
||||
นั้นไม่ใช่เพียงแค่มาโครที่ลิงก์ไปยังประเภทอื่น ๆ แต่ `char` คือประเภทของมันเอง
|
||||
|
||||
=== คีย์เวิร์ด
|
||||
|
||||
- `bool`, `true`, `false`, `char`, `int`, `short`, `long`, `signed`, `unsigned`,
|
||||
+ `bool`, `true`, `false`, `char`, `int`, `short`, `long`, `signed`, `unsigned`,
|
||||
`float`, `double`.
|
||||
- `_Bool`, `_BitInt`, `_Complex`, `_Imaginary`, `_Decimal32`, `_Decimal64`,
|
||||
+ `_Bool`, `_BitInt`, `_Complex`, `_Imaginary`, `_Decimal32`, `_Decimal64`,
|
||||
`_Decimal128`.
|
||||
|
||||
=== ระยะค่าที่เก็บได้
|
||||
|
||||
#i ตารางต่อไปนี้ให้ข้อมูลเกี่ยวกับขอบเขตของประเภทข้อมูลต่าง ๆ
|
||||
|
||||
#i ก่อนมาตรฐาน C23 มาตรฐาน C อนุญาตการแทนตัวเลขแบบใดก็ได้ และระยะขั้นต่ำของตัวเลข N บิตคือ
|
||||
#math.equation($-(2^(N-1)-1)$, alt: "ลบ 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1") ถึง
|
||||
#math.equation($+2^(N-1)-1$, alt: "บวก 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1") (เช่น *-127*
|
||||
ถึง *127* สำหรับประเภทตัวเลข 8 บิต) ซึ่งตรงกับขอบเขตของส่วนเติมเต็มหนึ่ง (one's complement)
|
||||
#h(9.75em) ก่อนมาตรฐาน C23 มาตรฐาน C อนุญาตการแทนตัวเลขแบบใดก็ได้ และระยะขั้นต่ำของตัวเลข
|
||||
N บิตคือ #math.equation($-(2^(N-1)-1)$, alt: "ลบ 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1") ถึง
|
||||
#math.equation($+2^(N-1)-1$, alt: "บวก 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1") (เช่น -127 ถึง
|
||||
127 สำหรับประเภทตัวเลข 8 บิต) ซึ่งตรงกับขอบเขตของส่วนเติมเต็มหนึ่ง (one's complement)
|
||||
หรือการแทนจำนวนมีเครื่องหมาย (sign-and-magnitude)
|
||||
|
||||
#i อย่างไรก็ตาม รูปแบบข้อมูลที่ใช้กันอย่างแพร่หลายทั้งหมด (รวมถึง ILP32, LP32, LP64, และ
|
||||
LLP64) และคอมไพเลอร์ C เกือบทั้งหมดใช้การแทนตัวเลขแบบส่วนเติมเต็มสอง (two's complement)
|
||||
(มีข้อยกเว้นที่ทราบแค่บางคอมไพเลอร์สำหรับระบบ UNISYS) และตั้งแต่มาตรฐาน C23
|
||||
#h(9.75em) อย่างไรก็ตาม รูปแบบข้อมูลที่ใช้กันอย่างแพร่หลายทั้งหมด (รวมถึง ILP32, LP32, LP64,
|
||||
และ LLP64) และคอมไพเลอร์ C เกือบทั้งหมดใช้การแทนตัวเลขแบบส่วนเติมเต็มสอง (two's
|
||||
complement) (มีข้อยกเว้นที่ทราบแค่บางคอมไพเลอร์สำหรับระบบ UNISYS) และตั้งแต่มาตรฐาน C23
|
||||
มันคือการแทนตัวเลขแบบเดียวที่ถูกอนุญาตให้ใช้โดยมาตรฐาน และมีขอบเขตที่แน่นอนระหว่าง
|
||||
#math.equation($-2^(N-1)$, alt: "ลบ 2 ยกกำลัง N ลบ 1") ถึง #math.equation(
|
||||
$+2^(N-1)-1$,
|
||||
alt: "บวก 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1",
|
||||
) (เช่น *-128* ถึง *127* สำหรับประเภทตัวเลข 8 บิต)
|
||||
) (เช่น -128 ถึง 127 สำหรับประเภทตัวเลข 8 บิต)
|
||||
|
||||
(มีการเพิ่มจุลภาคในทศนิยมเพื่อเพิ่มความสะดวกในการอ่าน)
|
||||
#h(9.75em) ตารางต่อไปนี้ให้ข้อมูลเกี่ยวกับขอบเขตของประเภทข้อมูลต่าง ๆ (มีการเพิ่มจุลภาคในทศนิยมเพื่อเพิ่มความสะดวกในการอ่าน)
|
||||
|
||||
#show table.cell.where(x: 0): strong
|
||||
#show math.equation.where(block: true): set block(spacing: 0.6em)
|
||||
@@ -439,17 +589,17 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
[IEEE-754],
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:
|
||||
+ min subnormal:
|
||||
#math.equation(
|
||||
$± 1.401,298,4 · 10^(-45)$,
|
||||
alt: "บวกลบ 1.4012984 คูณ 10 ยกกำลัง -45",
|
||||
)
|
||||
- min normal:
|
||||
+ min normal:
|
||||
#math.equation(
|
||||
$± 1.175,494,3 · 10^(-38)$,
|
||||
alt: "บวกลบ 1.1754943 คูณ 10 ยกกำลัง -38",
|
||||
)
|
||||
- max: \
|
||||
+ max: \
|
||||
#math.equation(
|
||||
$± 3.402,823,4 · 10^(38)$,
|
||||
alt: "บวกลบ 3.4028234 คูณ 10 ยกกำลัง 38",
|
||||
@@ -459,11 +609,11 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
),
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:\
|
||||
+ min subnormal:\
|
||||
`±0x1p-149`
|
||||
- min normal:\
|
||||
+ min normal:\
|
||||
`±0x1p-126`
|
||||
- max:\
|
||||
+ max:\
|
||||
`±0x1.fffffep+127`
|
||||
],
|
||||
align: left,
|
||||
@@ -473,19 +623,19 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
[IEEE-754],
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:
|
||||
+ min subnormal:
|
||||
#math.equation(
|
||||
$± 4.940,656,458,412\ · 10^(-324)$,
|
||||
alt: "บวกลบ 4.940656458412 คูณ 10 ยกกำลัง ลบ 324",
|
||||
block: true,
|
||||
)
|
||||
- min normal:
|
||||
+ min normal:
|
||||
#math.equation(
|
||||
$± 2.225,073,858,507,201,\ 4 · 10^(-308)$,
|
||||
alt: "บวกลบ 2.2250738585072014 คูณ 10 ยกกำลัง ลบ 308",
|
||||
block: true,
|
||||
)
|
||||
- max:
|
||||
+ max:
|
||||
#math.equation(
|
||||
$± 1.797,693,134,862,315,\ 7 · 10^308$,
|
||||
alt: "บวกลบ 1.7976931348623157 คูณ 10 ยกกำลัง 308",
|
||||
@@ -496,11 +646,11 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
),
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:
|
||||
+ min subnormal:
|
||||
`±0x1p-1074`
|
||||
- min normal:\
|
||||
+ min normal:\
|
||||
`±0x1p-1022`
|
||||
- max: `±0x1` \ `.fffffffffffffp+1023`
|
||||
+ max: `±0x1` \ `.fffffffffffffp+1023`
|
||||
],
|
||||
align: left,
|
||||
),
|
||||
@@ -527,19 +677,19 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
[x86],
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:
|
||||
+ min subnormal:
|
||||
#math.equation(
|
||||
$± 3.645,199,531,882,474,\ 602,528 · 10^(-4951)$,
|
||||
alt: "บวกลบ 3.645199531882474602528 คูณ 10 ยกกำลัง ลบ 4951",
|
||||
block: true,
|
||||
)
|
||||
- min normal:
|
||||
+ min normal:
|
||||
#math.equation(
|
||||
$± 3.362,103,143,112,093,\ 506,263 · 10^(-4932)$,
|
||||
alt: "บวกลบ 3.362103143112093506263 คูณ 10 ยกกำลัง ลบ 4932",
|
||||
block: true,
|
||||
)
|
||||
- max:
|
||||
+ max:
|
||||
#math.equation(
|
||||
$± 1.189,731,495,357,231,\ 765,021 · 10^(4932)$,
|
||||
alt: "บวกลบ 1.189731495357231765021 คูณ 10 ยกกำลัง 4932",
|
||||
@@ -550,11 +700,11 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
),
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:
|
||||
+ min subnormal:
|
||||
`±0x1p-16445`
|
||||
- min normal:
|
||||
+ min normal:
|
||||
`±0x1p-16382`
|
||||
- max: `±0x1.ffffffff`\ `fffffffep+16383`
|
||||
+ max: `±0x1.ffffffff`\ `fffffffep+16383`
|
||||
],
|
||||
align: left,
|
||||
),
|
||||
@@ -563,19 +713,19 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
[IEEE-754],
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:
|
||||
+ min subnormal:
|
||||
#math.equation(
|
||||
$± 6.475,175,119,438,025,\ 110,924,438,958,227,\ 646,552,5 · 10^(-4966)$,
|
||||
alt: "บวกลบ 6.4751751194380251109244389582276465525 คูณ 10 ยกกำลัง ลบ 4966",
|
||||
block: true,
|
||||
)
|
||||
- min normal:
|
||||
+ min normal:
|
||||
#math.equation(
|
||||
$± 3.362,103,143,112,093,\ 506,262,677,817,321,\ 752,602,6 · 10^(-4932)$,
|
||||
alt: "บวกลบ 3.3621031431120935062626778173217526026 คูณ 10 ยกกำลัง ลบ 4932",
|
||||
block: true,
|
||||
)
|
||||
- max:
|
||||
+ max:
|
||||
#math.equation(
|
||||
$± 1.189,731,495,357,231,\ 765,085,759,326,628,\ 007,016,2 · 10^4932$,
|
||||
alt: "บวกลบ 1.1897314953572317650857593266280070162 คูณ 10 ยกกำลัง 4932",
|
||||
@@ -586,11 +736,11 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
),
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:
|
||||
+ min subnormal:
|
||||
`±0x1p-16494`
|
||||
- min normal:
|
||||
+ min normal:
|
||||
`±0x1p-16382`
|
||||
- max: `±0x1.ffffffffffffff`\ `ffffffffffffffp+16383`
|
||||
+ max: `±0x1.ffffffffffffff`\ `ffffffffffffffp+16383`
|
||||
],
|
||||
align: left,
|
||||
),
|
||||
@@ -601,11 +751,11 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
[],
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:\
|
||||
+ min subnormal:\
|
||||
#math.equation($± 1 · 10^(-101)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 101")
|
||||
- min normal:\
|
||||
+ min normal:\
|
||||
#math.equation($± 1 · 10^(-95)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 95")
|
||||
- max:\
|
||||
+ max:\
|
||||
#math.equation(
|
||||
$± 9.999'999 · 10^96$,
|
||||
alt: "บวกลบ 9.999999 คูณ 10 ยกกำลัง 96",
|
||||
@@ -619,11 +769,11 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
[],
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:\
|
||||
+ min subnormal:\
|
||||
#math.equation($± 1 · 10^(-398)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ -398")
|
||||
- min normal:\
|
||||
+ min normal:\
|
||||
#math.equation($± 1 · 10^(-383)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 383")
|
||||
- max:
|
||||
+ max:
|
||||
#math.equation(
|
||||
$± 9.999'999'999'999'999\ · 10^384$,
|
||||
alt: "บวกลบ 9.999999999999999 คูณ 10 ยกกำลัง 384",
|
||||
@@ -638,17 +788,17 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
[],
|
||||
table.cell(
|
||||
[
|
||||
- min subnormal:\
|
||||
+ min subnormal:\
|
||||
#math.equation(
|
||||
$± 1 · 10^(-6176)$,
|
||||
alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 6176",
|
||||
)
|
||||
- min normal:\
|
||||
+ min normal:\
|
||||
#math.equation(
|
||||
$± 1 · 10^(-6143)$,
|
||||
alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 6143",
|
||||
)
|
||||
- max:
|
||||
+ max:
|
||||
#math.equation(
|
||||
$ ± 9.999'999'999'999'999'\ 999'999'999'999'999'999\ · 10^6144 $,
|
||||
alt: "บวกลบ 9.999999999999999999999999999999999 คูณ 10 ยกกำลัง 6144",
|
||||
@@ -665,11 +815,11 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
|
||||
== ชุดแปลโปรแกรมของกนู (GNU Compiler Collection; GCC)
|
||||
|
||||
#i ในกระบวนการการพัฒนาโครงงานนี้
|
||||
#h(6em) ในกระบวนการการพัฒนาโครงงานนี้
|
||||
ชุดแปลโปรแกรมของกนูนั้นถูกใช้เป็นหลักเนื่องจากเป็นชุดแปลโปรแกรม (คอมไพเลอร์; Compiler)
|
||||
ที่ใช้เป็นหลักในการพัฒนาโคดที่สร้างบนพื้นฐาน Arduino และบอร์ดต่าง ๆ รวมถึงบอร์ด ESP32
|
||||
|
||||
#i ชุดคอมไพเลอร์ GNU (GNU Compiler Collection; GCC) (เดิมชื่อ GNU C Compiler)
|
||||
#h(6em) ชุดคอมไพเลอร์ GNU (GNU Compiler Collection; GCC) (เดิมชื่อ GNU C Compiler)
|
||||
คือชุดคอมไพเลอร์จากโครงการ GNU ที่รองรับภาษาโปรแกรม สถาปัตยกรรมฮาร์ดแวร์
|
||||
และระบบปฏิบัติการต่าง ๆ มูลนิธิซอฟต์แวร์เสรี (FSF) เผยแพร่ GCC
|
||||
ในฐานะซอฟต์แวร์เสรีภายใต้สัญญาอนุญาตสถูกเรียกาธารณะทั่วไปของ GNU (GNU GPL) GCC
|
||||
@@ -677,13 +827,13 @@ LLP64) และคอมไพเลอร์ C เกือบทั้งห
|
||||
Linux ด้วยโคดประมาณ 15 ล้านบรรทัดในปี 2019 GCC จึงเป็นหนึ่งในโปรแกรมฟรีที่ใหญ่ที่สุดเท่าที่เคยมีมา
|
||||
GCC มีบทบาทสำคัญในการเติบโตของซอฟต์แวร์เสรี ทั้งในฐานะเครื่องมือและตัวอย่าง
|
||||
|
||||
#i นอกจากจะเป็นคอมไพเลอร์อย่างเป็นทางการของระบบปฏิบัติการ GNU แล้ว GCC
|
||||
#h(6em) นอกจากจะเป็นคอมไพเลอร์อย่างเป็นทางการของระบบปฏิบัติการ GNU แล้ว GCC
|
||||
ยังได้รับการยอมรับให้เป็นคอมไพเลอร์มาตรฐานโดยระบบปฏิบัติการคอมพิวเตอร์สมัยใหม่ที่คล้ายกับ Unix อื่นๆ
|
||||
อีกมากมาย รวมถึงระบบปฏิบัติการ Linux ส่วนใหญ่ ระบบปฏิบัติการตระกูล BSD ส่วนใหญ่ก็เปลี่ยนมาใช้ GCC
|
||||
ไม่นานหลังจากเปิดตัว แม้ว่าหลังจากนั้น FreeBSD และ Apple macOS ได้เปลี่ยนมาใช้คอมไพเลอร์ Clang
|
||||
ส่วนใหญ่เป็นเพราะเหตุผลด้านลิขสิทธิ์ GCC ยังสามารถคอมไพเลอร์โคดสำหรับระบบปฏิบัติการ Windows,
|
||||
Android, iOS, Solaris, HP-UX, AIX และ MS-DOS ได้อีกด้วย
|
||||
|
||||
#i GCC ได้รับการพอร์ตไปยังแพลตฟอร์มและสถาปัตยกรรมชุดคำสั่งต่าง ๆ มากกว่าคอมไพเลอร์อื่น ๆ
|
||||
#h(6em) GCC ได้รับการพอร์ตไปยังแพลตฟอร์มและสถาปัตยกรรมชุดคำสั่งต่าง ๆ มากกว่าคอมไพเลอร์อื่น ๆ
|
||||
และถูกนำไปใช้งานอย่างกว้างขวางในฐานะเครื่องมือในการพัฒนาซอฟต์แวร์ทั้งแบบฟรีและแบบที่เป็นกรรมสิทธิ์
|
||||
นอกจากนี้ GCC ยังพร้อมใช้งานสำหรับระบบฝังตัวมากมาย รวมถึงชิปที่ใช้ ARM และ Power ISA
|
||||
|
||||
Reference in New Issue
Block a user