目次
1. 為什麼「C 語言 版本」很重要
C 語言自 1970 年代誕生以來,作為程式語言的基礎被廣泛使用。在那漫長的歷史中,制定了各種版本(標準),持續演進。 但是,C 語言的「版本是什麼意思? 為什麼需要意識到版本? C 語言因長期以來被廣泛用於許多系統與應用程式的開發,所以「程式碼是以哪個版本為前提撰寫的」以及「使用的編譯器遵循哪個版本」這些點,對程式碼相容性、可移植性,甚至可維護性都有重大影響。 實際上,C 語言的標準(版本)隨著時代進,會加入新功能與規範,並修正或廢除舊有規範。 例如「可變長度陣列」或「bool 型別」以及「執行緒相關的標準化」等,在舊版本中不存在,只有在一定以上的版本才能使用。 相反地,若使用新標準的編譯器編譯以舊規格撰寫的原始碼,可能會出現意想不到的錯誤或警告。 在本文中,將從「為什麼重要」的觀點,說明 C 語言的版本, ・各版本的差異 ・主要特點 ・實務上的選擇方式 ・以及最新的動向 將以易於理解的方式說明到此為止。期望本內容能對剛開始學習 C 語言的人、以及在現場使用的工程師,提供整理版本基礎知識的幫助。2. C 語言版本的基本結構與規格/編譯器的關係
C 語言的「版本」聽起來,程式設計初學者可能會有點混亂。 因為「版本」實際上有兩層含義。 一個是,C 語言本身的規格(標準規範)作為的版本。另一個是,C 語言編譯器軟體的版本。C 語言規格(標準規範)的版本是什麼?
C 語言的標準規格是由國際標準化組織(ISO)以及美國國家標準協會(ANSI)等制定的。 每個規格都有「C89」「C99」「C11」「C17」「C23」等版本名稱。 這些版本規定了「可以怎樣寫程式」「具備哪些功能」「會有什麼行為」等,C 語言程式的規則本身。編譯器的版本是什麼?
另一方面,用於編寫 C 語言程式的「編譯器」(例如 GCC、Clang、Visual Studio 等)也各自有軟體版本。 編譯器決定了「支援到哪個 C 語言規格」,較新的編譯器會支援較新的規格。 例如,GCC 依版本支援 C99、C11、C17 等,而 Visual Studio 從 2019 版之後也能使用許多 C11 功能。先弄清規格與編譯器的差異
- C 語言規格的版本=語言的規則手冊
- 編譯器的版本=遵循規則手冊的程度,以及提供功能的軟體演進
3. C語言版本列表與演變
C語言自誕生以來,多次進行標準的修訂。每個版本都有其特色的功能新增或規格變更。在此,我們將依時間順序說明主要的版本。3.1 C89/C90(ANSI C/ISO C)
最初被標準化的C語言是「C89(ANSI X3.159-1989)」。它由美國國家標準協會(ANSI)制定,之後幾乎相同內容由國際標準化組織(ISO)以「C90(ISO/IEC 9899:1990)」發佈。 特點:- 標準函式庫與語言規格被明確化,C語言程式的可移植性大幅提升
- 從先前的“K&R C”起,函式宣告方式、型別檢查等變得更嚴格
- 基本語法與許多標準函式在此階段被整理
3.2 C99(ISO/IEC 9899:1999)
C99 是大幅推進 C 語言現代化的標準。加入了許多提升程式設計師便利性的功能。 主要新增與變更點:- 可變長度陣列(VLA)
- 使用
//
的單行註解 - 引入標準的
bool
型別與long long int
型別 - 內聯函式
inline
- 支援複數(complex 數)
- 初始化子更彈性的寫法(如陣列的中括號初始化等)
3.3 C11(ISO/IEC 9899:2011)
C11 是加強對現代開發環境與平行處理支援的標準。 主要新增與變更點:- 執行緒(多執行緒)的標準化(
<threads.h>
) - 原子操作與記憶體模型(提升平行處理的安全性)
- 加入靜態斷言
_Static_assert
- 泛型巨集
_Generic
- 對齊控制與 Unicode 支援的強化
3.4 C17/C18(ISO/IEC 9899:2018)
C17(亦稱為 C18)主要是 C11 的錯誤修正與次要規格調整,沒有新增大型功能。 特點:- 以錯誤修正與模糊規格的釐清為主
- 在實務上與 C11 幾乎相同地使用
3.5 C23(ISO/IEC 9899:2024)
C23 是於 2024 年正式化的最新標準。受到近年其他語言趨勢與程式開發需求的影響,導入了大量新功能。 主要新增與變更點:- 加入
nullptr
關鍵字(提升與 C++ 的相容性) - 引入二進位字面值(例如:
0b1010
) - 支援
char8_t
型別(明確的 UTF-8 型別) - 新增與統一標準屬性
- 加強位元操作函式
- 為提升可讀性而進行細部語法改良
4. 各版本的選擇方式與實務建議
C 語言有多個規格版本存在,但在實際撰寫程式時,意識「使用哪個版本」是很重要的。這裡將說明現場的版本選擇考量、常見問題的避免方法,以及在實務上有用的技巧。版本選擇的基本方針
1. 原則上優先使用較新的規格
如果可能,建議使用較新的規格(C11、C17、C23)。較新的規格已針對錯誤修正、提升安全性以及改善程式設計的便利性。2. 配合既有程式碼與使用環境
然而,在既有系統、函式庫、嵌入式開發等情況下,往往需要配合較舊的規格(C90/C99)。此外,嵌入式用途也可能受到編譯器支援狀況的限制。如何檢查規格符合性
在 C 語言中,使用前處理器巨集__STDC_VERSION__
可以簡單判斷編譯器支援哪個規格。#include <stdio.h>
int main(void) {
#if __STDC_VERSION__ >= 202311L
printf("C23 (ISO/IEC 9899:2024)支援n");
#elif __STDC_VERSION__ >= 201710L
printf("C17/C18支援n");
#elif __STDC_VERSION__ >= 201112L
printf("C11支援n");
#elif __STDC_VERSION__ >= 199901L
printf("C99支援n");
#elif __STDC_VERSION__ >= 199409L
printf("C95支援n");
#else
printf("C89/C90支援n");
#endif
return 0;
}
如此一來,使用 __STDC_VERSION__
巨集即可確認各環境的規格版本。
實務上常見的注意事項
- 確認編譯器的支援狀況 並非所有編譯器都完全支援最新規格。例如,GCC 與 Clang 會較快支援較新的規格,但 Visual Studio 與嵌入式編譯器的支援可能較慢。
- 有時需要指定選項
某些編譯器若未在命令列選項中明確指定規格版本,則無法使用新功能。例如:
gcc -std=c11 sample.c
- 考量可移植性與維護性 在大型開發或長期運營的專案中,為了優先考慮維護性與可移植性,可能會刻意使用較舊的規格。
版本選擇的實踐指南
- 新專案或學習用途:建議使用 C11 或 C17
- 嵌入式或舊系統相容:C99 與 C90 也是選項
- 想積極使用最新功能:在調查 C23 支援狀況後再考慮
- 多人、多環境開發:事先共享所有人的編譯器支援狀況
5. 未來的趨勢與 C23 之後
C 語言隨著時代的變遷持續演進。2024 年,C23 終於正式獲得國際標準的認可。本文將說明 C23 的重點以及未來 C 語言標準的展望。C23 的正式化與主要新功能
C23(ISO/IEC 9899:2024)為了因應現代需求,加入了許多功能與改進。以下列出主要的新功能與改良點。- 新增 nullptr 關鍵字
與 C++ 相同,現在可以將
nullptr
作為「指標的明確 NULL 值」使用。這提升了可讀性,也有助於防止錯誤。 - 引入二進制字面值
在此之前 C 語言無法直接表示二進制,但從 C23 起可使用如
0b1010
的二進制字面值。 - 新增 char8_t 型
加入專為 UTF-8 設計的字元型別
char8_t
,使多位元組字元的處理更直觀。 - 加強標準屬性與位元操作函式 提供了更注重程式碼可讀性與最佳化的屬性,以及擴充的位元操作標準函式。
- 細部語法與功能的改進 包含許多針對錯誤處理、安全性以及符合現代程式設計風格的改良。
C23 的採用情況與未來的普及
由於 C23 於 2024 年剛剛公布標準,尚未能立即在所有編譯器與開發環境中使用。開源編譯器如 GCC、Clang 正在逐步支援 C23,但完整實作與普及仍需時間。 在可預見的未來,C11 與 C17 仍將是主流。然而,預計在未來數年內,主要編譯器將加速支援,使利用 C23 功能的現代開發風格得以普及。未來的 C 語言展望
C 語言已具備相當穩定的規格,甚至被稱為「老舊語言」,但預計仍會持續根據使用者需求與其他語言的趨勢逐步演進。AI、IoT、嵌入式開發等領域的需求仍然強勁,未來持續關注「C 語言版本」仍具重要意義。 此外,未來很可能會持續定期進行標準修訂,保持對最新動向的關注,有助於在實務上取得優勢並避免問題。6. 總結
C 語言自誕生以來已接近半個世紀,至今仍廣泛應用於許多系統與軟體開發現場。其背後是作為「C 語言 版本」累積的眾多標準修訂與演進。 本文廣泛說明了 C 語言各版本的特點與變遷,以及實務上的選擇方式與注意事項,甚至涵蓋最新標準 C23 的動向。意識版本的好處
- 提升維護性 明確了解所基於的標準,可使未來的維護與規格變更的因應更為容易。
- 確保可移植性 在不同開發環境或編譯器之間,程式碼的重用與共享更為容易。
- 預防問題 即使在將舊程式碼移植至新環境,或使用新功能時,事先了解版本差異即可避免意外的錯誤與不相容問題。
實務上可活用的版本選擇
對於初學者而言,從功能完整且參考資訊豐富的「C99」或「C11」開始學習較為實際。 在實務開發時,請依據所使用的編譯器與既有系統的相容性,選擇最適的版本。將目光放在現代 C 語言的升級上
雖然像 C23 這樣的最新標準在實務導入上需要時間,但它有助於未來程式設計的效率提升與安全性增進。 未來仍需關注 C 語言版本的演進,並視需求持續更新知識與技能。 正確理解「C 語言 版本」,並依情況作出選擇與運用,才能促成更安全且高效的開發。 若本文能成為各位在實務或學習上的參考,將不勝感激。7. FAQ(常見問題)
在此,我們彙總了關於「C 語言 版本」的常見問題及其回答。從初學者到現場工程師,精選了有助於解決疑惑的內容。Q1. 編譯器的版本與 C 語言標準的版本是一樣的嗎?
A. 不同。 C 語言標準的版本是「語言規範本身」的基準,像是「C99」「C11」「C23」等。另一方面,編譯器的版本則顯示該軟體的演進程度。 例如即使是 GCC 或 Clang 的最新版本,若未明確指定「-std=c11」等,仍可能不會進入符合標準的模式,請特別留意。Q2. 舊的標準(C90 與 C95)現在仍有學習的意義嗎?
A. 有的。 即使在現在,許多企業與嵌入式開發現場仍重視相容性與遺留資產,採用符合 C90 或 C95 標準的開發。了解過去的標準對於故障排除與維護工作必定有幫助。Q3. 最新標準 C23 應該立即使用嗎?
A. 需要謹慎判斷。 C23 剛於 2024 年正式定稿,尚未在所有編譯器與開發環境中完全支援。對於新專案或個人學習,先行嘗試使用也是不錯的,但在實務上務必確認編譯器的支援狀況以及整個團隊的開發環境。Q4. __STDC_VERSION__
的值能判斷自己的環境符合哪個標準嗎?
A. 可以,能判斷。 __STDC_VERSION__
是一個顯示編譯器所支援的 C 語言標準版本的巨集。
主要的值例如如下:巨集值 | 標準名稱 |
---|---|
199409L | C95 |
199901L | C99 |
201112L | C11 |
201710L | C17/C18 |
202311L | C23 |