Files
liteauthdocs/Chapter2/CLanguage.typ
T
2025-12-31 21:54:51 +07:00

690 lines
40 KiB
Typst

#import "../PageTemplate.typ": *
#import "@preview/i-figured:0.2.4"
= ภาษาซี (C Programming Language) <cprogramming>
#i ภาษาซีเป็นภาษาโปรแกรมสำหรับวัตถุประสงค์ทั่วไปสร้างขึ้นในช่วงทศวรรษ 1970
โดยเดนนิสริตชีและยังคงได้รับความนิยมและใช้งานอย่างกว้างขวางด้วยการออกแบบภาษาซีทำให้โปรแกรมเมอร์สามารถเข้าถึงคุณลักษณะต่างๆของสถาปัตยกรรมซีพียูทั่วไปได้โดยตรง
ซึ่งปรับแต่งให้เหมาะกับชุดคำสั่ง เป้าหมาย ภาษาซี
ถูกนำมาใช้และยังคงนำมาใช้ในการพัฒนาระบบปฏิบัติการไดรเวอร์อุปกรณ์และสแต็กโปรโตคอลแต่การใช้งานในซอฟต์แวร์แอปพลิเคชั่นกำลังลดลงภาษาซีถูกนำมาใช้ในคอมพิวเตอร์ตั้งแต่ซูเปอร์คอมพิวเตอร์ขนาดใหญ่ที่สุดไปจนถึงไมโครคอนโทรลเลอร์ขนาดเล็กที่สุดและระบบฝังตัว
#i
ภาษาซีเป็นภาษาเชิงกระบวนการที่จำเป็นรองรับการเขียนโปรแกรมแบบมีโครงสร้างขอบเขตตัวแปรเชิงศัพท์และการเรียกซ้ำด้วยระบบชนิดข้อมูลแบบคงที่ภาษาซีถูกออกแบบมาเพื่อการคอมไพล์เพื่อให้สามารถเข้าถึงหน่วยความจำ
และโครงสร้างภาษา ในระดับต่ำซึ่งแมปกับคำสั่งเครื่องได้อย่างมีประสิทธิภาพ โดยทั้งหมดนี้รองรับรันไทม์ขั้นต่ำ
แม้จะมีความสามารถในระดับต่ำ แต่ภาษาซีก็ถูกออกแบบมาเพื่อสนับสนุนการเขียนโปรแกรมข้ามแพลตฟอร์ม
โปรแกรมซี
ที่สอดคล้องกับมาตรฐานที่เขียนขึ้นโดยคำนึงถึงความสามารถในการพกพาสามารถคอมไพล์สำหรับแพลตฟอร์มคอมพิวเตอร์และระบบปฏิบัติการที่หลากหลาย
โดยมีการเปลี่ยนแปลงซอร์สโคดเพียงเล็กน้อย
#i แม้ว่าทั้งภาษาซีและไลบรารีมาตรฐานของภาษา ซีจะไม่ได้มีคุณสมบัติยอดนิยมบางอย่างที่พบในภาษาอื่น
แต่ก็มีความยืดหยุ่นเพียงพอที่จะรองรับคุณสมบัติเหล่านั้นได้
ตัวอย่างเช่นการวางแนววัตถุและการเก็บขยะนั้นจัดทำโดยไลบรารีภายนอก GLib Object System และ
Boehm garbage collector ตามลำดับ
#i ตั้งแต่ปี 2000 เป็นต้นมาภาษาซี ได้รับการจัดอันดับอย่างต่อเนื่องให้อยู่ในอันดับสี่ภาษาสูงสุดในดัชนี TIOBE
ซึ่งเป็นการวัดความนิยมของภาษาการเขียนโปรแกรม
== ประวัติ
=== การพัฒนาช่วงแรก
==== ภาษา B
==== ภาษา B ใหม่และ C รุ่นแรก
==== โครงสร้างและการเขียน Unix kernel ใหม่
=== K&R C
=== ANSI C และ ISO C
=== C99
=== C11
=== C17
=== C23
=== C2Y
=== Embedded C
== ตัวแปร (Variables)
#i ตัวแปรในภาษา C เบื้องต้นแล้วประกอบไปด้วยประเภทของข้อมูล และชื่อตัวแปร
โดยที่ชื่อตัวแปรนั้นสามารถเป็นรายการที่ถูกแบ่งด้วยเครื่องหมายจุลภาคได้ด้วยเช่นกัน ตัวอย่างคือ
```c
int data;
float a, b, c;
```
== ประเภทข้อมูล (Data Types)
#i ข้อมูลที่เกี่ยวข้องกับตัวเลขมักมีประเภท *unsigned* และ *signed* โดยความแตกต่างหากอธิบายสั้น
คือ
- *Signed (มีเครื่องหมาย):* ตัวเลขที่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ -128 ถึง 127
- *Unsigned (ไม่มีเครื่องหมาย):* ตัวเลขที่ไม่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ 0 ถึง 255
#i จะสังเกตได้ว่า ข้อมูลประเภท unsigned นั้นสามารถเก็บตัวเลขบวกได้จำนวนมากกว่า คือสูงสุดที่ 255
แต่หากนำค่าสัมบูรณ์ (absolute value) ของระยะข้อมูลแบบ signed มาบวกกัน เช่น\
#math.equation($|-128| + |127|$, alt: "ค่าสัมบูรณ์ของ -128 บวกค่าสัมบูรณ์ของ 127")
จะพบว่าได้ค่า 255 หมายความว่า จริง แล้วข้อมูลประเภท signed สามารถเก็บข้อมูลได้ 255
ตัวเลขเช่นกัน เพียงแต่ว่าครึ่งหนึ่งของตัวเลขที่สามารถเก็บได้เป็นตัวเลขติดลบ
*หมายเหตุ:* เลขคณิตจำนวนเต็มมีนิยามแตกต่างกันสำหรับชนิดจำนวนเต็มแบบ signed และ unsigned
โปรดดูตัวดำเนินการเลขคณิต โดยเฉพาะอย่างยิ่งการโอเวอร์โฟลว์จำนวนเต็ม
=== ประเภทบูลีน (Boolean)
*หมายเหตุ:* ประเภทบูลีนนั้นถูกนำเสนอครั้งแรกในมาตรฐาน C99
โดยการกล่าวถึงประเภทข้อมูลบูลีนนั้น ในประวัติของภาษา C แล้วมีสองแบบ
- `_Bool` (และมีมาโคร `bool`): จนถึงมาตรฐาน C23
- `bool` (ที่ไม่ใช่แค่มาโคร): มีตั้งแต่มาตรฐาน C23
=== ประเภทจำนวนเต็ม (Integer)
- `short int` (หรืออีกชื่อหนึ่งคือ `short` และสามารถใช้คีย์เวิร์ด `signed` ได้)
- `unsigned short int` (หรือ `unsigned short`)
- `int` (หรือ `signed int`) \
คือประเภทข้อมูลตัวเลขที่ปกติที่สุด และจะถูกการันตีว่าจะมีขนาดขั้นต่ำ 16 บิตเสมอ
โดยระบบทั่วไปส่วนใหญ่ในปัจจุบันจะเป็น 32 บิต
- `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 แบบมีขนาดชัดเจน โดย
n แทนด้วยจำนวนบิต (รวมถึงบิตเครื่องหมาย และ n จะต้องไม่มากกว่า `BITINT_MAXWIDTH`
จากไฟล์ `<limits.h>`)
- `unsigned _BitInt(n)`: เหมือนข้างต้น เพียงแค่เป็นประเภท unsigned
(และไม่มีบิตเครื่องหมาย)
และเหมือนประเภทข้อมูลอื่น คุณสามารถเรียงคีย์เวิร์ดแบบใดก็ได้ เช่น `unsigned long long int`
และ `long int unsigned long` นั้นเหมือนกัน
ตารางต่อไปนี้สรุปประเภทตัวเลขทั้งหมดและคุณสมบัติของมัน
#show table.cell.where(y: 1): strong
#show table.cell: set par(justify: false, leading: 0.5em)
#figure(
table(
columns: 7,
align: horizon + center,
table.header(
table.cell([ชื่อประเภท], rowspan: 2),
table.cell([ประเภทเทียบเท่า], rowspan: 2),
table.cell([จำนวนบิตตามรูปแบบข้อมูล], colspan: 5),
[มาตรฐาน C],
[LP32],
[ILP32],
[LLP64],
[LP64],
),
table.cell(`char`, align: left),
`char`,
table.cell([อย่างน้อย\ *8*], rowspan: 3),
table.cell([*8*], rowspan: 3),
table.cell([*8*], rowspan: 3),
table.cell([*8*], rowspan: 3),
table.cell([*8*], rowspan: 3),
table.cell(`signed char`, align: left),
`signed char`,
table.cell(`unsigned char`, align: left),
`unsigned char`,
table.cell(`short`, align: left),
table.cell(`short int`, rowspan: 4),
table.cell([อย่างน้อย\ *16*], rowspan: 6),
table.cell([*16*], rowspan: 6),
table.cell([*16*], rowspan: 6),
table.cell([*16*], rowspan: 6),
table.cell([*16*], rowspan: 6),
table.cell(`short int`, align: left),
table.cell(`signed short`, align: left),
table.cell(`signed short int`, align: left),
table.cell(`unsigned short`, align: left),
table.cell([`unsigned`\ `short int`], rowspan: 2),
table.cell(`unsigned short int`, align: left),
table.cell(`int`, align: left),
table.cell(`int`, rowspan: 3),
table.cell([อย่างน้อย\ *16*], rowspan: 5),
table.cell([*16*], rowspan: 5),
table.cell([*32*], rowspan: 5),
table.cell([*32*], rowspan: 5),
table.cell([*32*], rowspan: 5),
table.cell(`signed`, align: left),
table.cell(`signed int`, align: left),
table.cell(`unsigned`, align: left),
table.cell([`unsigned int`], rowspan: 2),
table.cell(`unsigned int`, align: left),
table.cell(`long`, align: left),
table.cell(`long int`, rowspan: 4),
table.cell([อย่างน้อย\ *32*], rowspan: 6),
table.cell([*32*], rowspan: 6),
table.cell([*32*], rowspan: 6),
table.cell([*32*], rowspan: 6),
table.cell([*64*], rowspan: 6),
table.cell(`long int`, align: left),
table.cell(`signed long`, align: left),
table.cell(`signed long int`, align: left),
table.cell(`unsigned long`, align: left),
table.cell([`unsigned`\ `long int`], rowspan: 2),
table.cell(`unsigned long int`, align: left),
),
caption: [ขนาดของข้อมูลเป็นบิต],
)
#pagebreak()
#figure(
table(
columns: 7,
align: horizon + center,
table.header(
table.cell([ชื่อประเภท], rowspan: 2),
table.cell([ประเภทเทียบเท่า], rowspan: 2),
table.cell([จำนวนบิตตามรูปแบบข้อมูล], colspan: 5),
[มาตรฐาน C],
[LP32],
[ILP32],
[LLP64],
[LP64],
),
table.cell(`long long`, align: left),
table.cell([`long long int` (C99)], rowspan: 4),
table.cell([อย่างน้อย\ *64*], rowspan: 6),
table.cell([*64*], rowspan: 6),
table.cell([*64*], rowspan: 6),
table.cell([*64*], rowspan: 6),
table.cell([*64*], rowspan: 6),
table.cell(`long long int`, align: left),
table.cell(`signed long long`, align: left),
table.cell(`signed long long int`, align: left),
table.cell(`unsigned long long`, align: left),
table.cell([`unsigned long`\ `long int` (C99)], rowspan: 2),
table.cell(`unsigned long long int`, align: left),
),
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 คือรูปแบบการเก็บข้อมูลของโปรแกรมซึ่งเป็นสิ่งที่กำหนดขนาดของตัวแปร
โดยรูปแบบข้อมูลนั้นจะถูกกำหนดโดยแพลตฟอร์มเป้าหมาย
ซึ่งมีหน่วยประมวลผลและระบบปฏิบัติการเป็นปัจจัยหลัก โดยตามตารางในหัวข้อก่อนหน้า หลัก
แล้วมีรูปแบบข้อมูลอยู่ 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) ประเภท
- `float`: จำนวนทศนิยมความแม่นยำเดี่ยว ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary32 หากรองรับ
- `double`: จำนวนทศนิยมความแม่นยำสองเท่า ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary64
หากรองรับ
- `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 ที่รู้จักกันอย่างแพร่หลายที่สุดคือรูปแบบความแม่นยำเพิ่มเติม
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
มิฉะนั้น ประเภทตัวเลขทศนิยมเพิ่มเติมเหล่านี้จะไม่ถูกรองรับ
ข้อมูลประเภททศนิยมอาจรองรับค่าพิเศษเพิ่มเติมได้แก่
- อนันต์ (Infinity, ทั้งบวกและลบ)
- ศูนย์ติดลบ, `-0.0` โดยมีค่าเท่ากับศูยน์ที่ติดบวก แต่อาจมีความหมายในบางสมการ เช่น
`1.0 / 0.0 == INFINITY` แต่ `1.0 / -0.0 == -INFINITY`
- ไม่ใช่ตัวเลข (not-a-number; NaN) ซึ่งไม่เท่ากับอะไรเลย (รวมถึงตัวมันเอง)
ทศนิยมจำนวนจริงสามารถถูกใช้กับตัวดำเนินการทางคณิตศาสตร์ได้ *+ - / \**
และฟังก์ชันทางคณิตศาสตร์จาก `<math.h>`
โดยทั้งตัวดำเนินการและฟังก์ชันจากไลบรารีนั้นสามารถก่อให้เกิดการแสดงข้อผิดพลาดของจำนวนทศนิยมได้และจะตั้งค่า
`errno`
=== ประเภทจำนวนทศนิยมซับซ้อน (Complex floating types)
#i ประเภทข้อมูลจำนวนทศนิยมซับซ้อนนั้นเป็นประเภทที่แทนตัวเลขเชิงซ้อน (complex number) นั้นคือ
ตัวเลขที่สามารถถูกเขียนแทนเป็นผลรวมของจำนวนจริงและจำนวนจริงที่คูณด้วยจำนวนจินตภาพ:
#math.equation($a + b i$, alt: "a บวก b i")
ประเภทจำนวนเชิงซ้อนมีอยู่สามประเภท ได้แก่
- ```c float _Complex``` (และสามารถใช้ ```c float 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)
#i ประเภทข้อมูลจำนวนทศนิยมจินตภาพนั้นเป็นประเภทที่แทนตัวเลขจินตภาพ (imaginary number) นั้นคือ
ตัวเลขที่สามารถถูกเขียนแทนเป็นจำนวนจริงที่คูณด้วยจำนวนจินตภาพ: #math.equation(
$b i$,
alt: "b i",
)
ประเภทจำนวนเชิงซ้อนมีอยู่สามประเภท ได้แก่
- ```c float _Imaginary``` (และสามารถใช้ ```c float 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` หรือ
`unsigned char` ก็ได้ขึ้นอยู่กับแพลตฟอร์มและคอมไพเลอร์ แต่อย่างไรก็ตาม `char`
นั้นไม่ใช่เพียงแค่มาโครที่ลิงก์ไปยังประเภทอื่น ๆ แต่ `char` คือประเภทของมันเอง
=== คีย์เวิร์ด
- `bool`, `true`, `false`, `char`, `int`, `short`, `long`, `signed`, `unsigned`,
`float`, `double`.
- `_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)
หรือการแทนจำนวนมีเครื่องหมาย (sign-and-magnitude)
#i อย่างไรก็ตาม รูปแบบข้อมูลที่ใช้กันอย่างแพร่หลายทั้งหมด (รวมถึง 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 บิต)
(มีการเพิ่มจุลภาคในทศนิยมเพื่อเพิ่มความสะดวกในการอ่าน)
#show table.cell.where(x: 0): strong
#show math.equation.where(block: true): set block(spacing: 0.6em)
#set list(indent: 0em)
#figure(
table(
columns: 5,
align: horizon + center,
table.header(
table.cell([ประเภท], rowspan: 2),
table.cell([ขนาด\ (บิต)], rowspan: 2),
table.cell([รูปแบบ], rowspan: 2),
table.cell([ระยะค่า], colspan: 2),
[โดยประมาณ], [แน่นอน],
),
table.cell([ตัวอักษร], rowspan: 4),
table.cell([8], rowspan: 2),
[signed],
[],
[*-128* ถึง *127*],
[unsigned],
[],
[*0* ถึง *255*],
[16],
[UTF-16],
[],
[*0* ถึง *65535*],
[32],
[UTF-32],
[],
[*0* ถึง *1114111 (0x10ffff)*],
table.cell([จำนวน\ เต็ม], rowspan: 6),
table.cell([16], rowspan: 2),
[signed],
[*± 3.27 · 104*],
[*-32768* ถึง *32767*],
[unsigned],
[*0* ถึง *6.55 · 104*],
[*0* ถึง *65535*],
table.cell([32], rowspan: 2),
[signed],
[*± 2.14 · 109*],
[*-2,147,483,648* ถึง *2,147,483,647*],
[unsigned],
[*0* ถึง *4.29 · 109*],
[*0* ถึง *4,294,967,295*],
table.cell([64], rowspan: 2),
[signed],
[*± 9.22 · 1018*],
[*-9,223,372,036,854,775,808* ถึง *9,223,372,036,854,775,807*],
[unsigned],
[*0* ถึง *1.84 · 1019*],
[*0* ถึง *18,446,744,073,709,551,615*],
table.cell([ทศนิยม\ ไบนารี], rowspan: 2),
[32],
[IEEE-754],
table.cell(
[
- min subnormal:
#math.equation(
$± 1.401,298,4 · 10^(-45)$,
alt: "บวกลบ 1.4012984 คูณ 10 ยกกำลัง -45",
)
- min normal:
#math.equation(
$± 1.175,494,3 · 10^(-38)$,
alt: "บวกลบ 1.1754943 คูณ 10 ยกกำลัง -38",
)
- max: \
#math.equation(
$± 3.402,823,4 · 10^(38)$,
alt: "บวกลบ 3.4028234 คูณ 10 ยกกำลัง 38",
)
],
align: left,
),
table.cell(
[
- min subnormal:\
`±0x1p-149`
- min normal:\
`±0x1p-126`
- max:\
`±0x1.fffffep+127`
],
align: left,
),
[64],
[IEEE-754],
table.cell(
[
- min subnormal:
#math.equation(
$± 4.940,656,458,412\ · 10^(-324)$,
alt: "บวกลบ 4.940656458412 คูณ 10 ยกกำลัง ลบ 324",
block: true,
)
- min normal:
#math.equation(
$± 2.225,073,858,507,201,\ 4 · 10^(-308)$,
alt: "บวกลบ 2.2250738585072014 คูณ 10 ยกกำลัง ลบ 308",
block: true,
)
- max:
#math.equation(
$± 1.797,693,134,862,315,\ 7 · 10^308$,
alt: "บวกลบ 1.7976931348623157 คูณ 10 ยกกำลัง 308",
block: true,
)
],
align: left,
),
table.cell(
[
- min subnormal:
`±0x1p-1074`
- min normal:\
`±0x1p-1022`
- max: `±0x1` \ `.fffffffffffffp+1023`
],
align: left,
),
),
caption: [ตารางแสดงขอบเขตประเภทข้อมูล],
)
#pagebreak()
#figure(
table(
columns: 5,
align: horizon + center,
table.header(
table.cell([ประเภท], rowspan: 2),
table.cell([ขนาด\ (บิต)], rowspan: 2),
table.cell([รูปแบบ], rowspan: 2),
table.cell([ระยะค่า], colspan: 2),
[โดยประมาณ], [แน่นอน],
),
table.cell([ทศนิยม\ ไบนารี], rowspan: 2),
[80],
[x86],
table.cell(
[
- min subnormal:
#math.equation(
$± 3.645,199,531,882,474,\ 602,528 · 10^(-4951)$,
alt: "บวกลบ 3.645199531882474602528 คูณ 10 ยกกำลัง ลบ 4951",
block: true,
)
- min normal:
#math.equation(
$± 3.362,103,143,112,093,\ 506,263 · 10^(-4932)$,
alt: "บวกลบ 3.362103143112093506263 คูณ 10 ยกกำลัง ลบ 4932",
block: true,
)
- max:
#math.equation(
$± 1.189,731,495,357,231,\ 765,021 · 10^(4932)$,
alt: "บวกลบ 1.189731495357231765021 คูณ 10 ยกกำลัง 4932",
block: true,
)
],
align: left,
),
table.cell(
[
- min subnormal:
`±0x1p-16445`
- min normal:
`±0x1p-16382`
- max: `±0x1.ffffffff`\ `fffffffep+16383`
],
align: left,
),
[128],
[IEEE-754],
table.cell(
[
- 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:
#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:
#math.equation(
$± 1.189,731,495,357,231,\ 765,085,759,326,628,\ 007,016,2 · 10^4932$,
alt: "บวกลบ 1.1897314953572317650857593266280070162 คูณ 10 ยกกำลัง 4932",
block: true,
)
],
align: left,
),
table.cell(
[
- min subnormal:
`±0x1p-16494`
- min normal:
`±0x1p-16382`
- max: `±0x1.ffffffffffffff`\ `ffffffffffffffp+16383`
],
align: left,
),
table.cell([ทศนิยม\ เดซิมอล], rowspan: 3),
[32],
[IEEE-754],
[],
table.cell(
[
- min subnormal:\
#math.equation($± 1 · 10^(-101)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 101")
- min normal:\
#math.equation($± 1 · 10^(-95)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 95")
- max:\
#math.equation(
$± 9.999'999 · 10^96$,
alt: "บวกลบ 9.999999 คูณ 10 ยกกำลัง 96",
)
],
align: left,
),
[64],
[IEEE-754],
[],
table.cell(
[
- min subnormal:\
#math.equation($± 1 · 10^(-398)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ -398")
- min normal:\
#math.equation($± 1 · 10^(-383)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 383")
- max:
#math.equation(
$± 9.999'999'999'999'999\ · 10^384$,
alt: "บวกลบ 9.999999999999999 คูณ 10 ยกกำลัง 384",
block: true,
)
],
align: left,
),
[128],
[IEEE-754],
[],
table.cell(
[
- min subnormal:\
#math.equation(
$± 1 · 10^(-6176)$,
alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 6176",
)
- min normal:\
#math.equation(
$± 1 · 10^(-6143)$,
alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 6143",
)
- max:
#math.equation(
$ ± 9.999'999'999'999'999'\ 999'999'999'999'999'999\ · 10^6144 $,
alt: "บวกลบ 9.999999999999999999999999999999999 คูณ 10 ยกกำลัง 6144",
block: true,
)
],
align: left,
),
),
caption: [ตารางแสดงขอบเขตประเภทข้อมูล (ต่อ)],
)
#set list(indent: 1em)
== ชุดแปลโปรแกรมของกนู (GNU Compiler Collection; GCC)
#i ในกระบวนการการพัฒนาโครงงานนี้
ชุดแปลโปรแกรมของกนูนั้นถูกใช้เป็นหลักเนื่องจากเป็นชุดแปลโปรแกรม (คอมไพเลอร์; Compiler)
ที่ใช้เป็นหลักในการพัฒนาโคดที่สร้างบนพื้นฐาน Arduino และบอร์ดต่าง ๆ รวมถึงบอร์ด ESP32
#i ชุดคอมไพเลอร์ GNU (GNU Compiler Collection; GCC) (เดิมชื่อ GNU C Compiler)
คือชุดคอมไพเลอร์จากโครงการ GNU ที่รองรับภาษาโปรแกรม สถาปัตยกรรมฮาร์ดแวร์
และระบบปฏิบัติการต่าง ๆ มูลนิธิซอฟต์แวร์เสรี (FSF) เผยแพร่ GCC
ในฐานะซอฟต์แวร์เสรีภายใต้สัญญาอนุญาตสถูกเรียกาธารณะทั่วไปของ GNU (GNU GPL) GCC
เป็นองค์ประกอบสำคัญของชุดเครื่องมือ GNU ซึ่งใช้สำหรับโครงการส่วนใหญ่ที่เกี่ยวข้องกับ GNU และเคอร์เนล
Linux ด้วยโคดประมาณ 15 ล้านบรรทัดในปี 2019 GCC จึงเป็นหนึ่งในโปรแกรมฟรีที่ใหญ่ที่สุดเท่าที่เคยมีมา
GCC มีบทบาทสำคัญในการเติบโตของซอฟต์แวร์เสรี ทั้งในฐานะเครื่องมือและตัวอย่าง
#i นอกจากจะเป็นคอมไพเลอร์อย่างเป็นทางการของระบบปฏิบัติการ GNU แล้ว GCC
ยังได้รับการยอมรับให้เป็นคอมไพเลอร์มาตรฐานโดยระบบปฏิบัติการคอมพิวเตอร์สมัยใหม่ที่คล้ายกับ Unix อื่นๆ
อีกมากมาย รวมถึงระบบปฏิบัติการ Linux ส่วนใหญ่ ระบบปฏิบัติการตระกูล BSD ส่วนใหญ่ก็เปลี่ยนมาใช้ GCC
ไม่นานหลังจากเปิดตัว แม้ว่าหลังจากนั้น FreeBSD และ Apple macOS ได้เปลี่ยนมาใช้คอมไพเลอร์ Clang
ส่วนใหญ่เป็นเพราะเหตุผลด้านลิขสิทธิ์ GCC ยังสามารถคอมไพเลอร์โคดสำหรับระบบปฏิบัติการ Windows,
Android, iOS, Solaris, HP-UX, AIX และ MS-DOS ได้อีกด้วย
#i GCC ได้รับการพอร์ตไปยังแพลตฟอร์มและสถาปัตยกรรมชุดคำสั่งต่าง ๆ มากกว่าคอมไพเลอร์อื่น ๆ
และถูกนำไปใช้งานอย่างกว้างขวางในฐานะเครื่องมือในการพัฒนาซอฟต์แวร์ทั้งแบบฟรีและแบบที่เป็นกรรมสิทธิ์
นอกจากนี้ GCC ยังพร้อมใช้งานสำหรับระบบฝังตัวมากมาย รวมถึงชิปที่ใช้ ARM และ Power ISA