當前定位
對於大專院校的學生而言,C 語言至今仍是不可或缺的開發工具,在學習「資料結構」時尤其關鍵。由於 C 語言沒有過多花俏的語法包裝,反而能讓學習者毫無阻礙地觀察底層容器操作與記憶體資料的變化。
然而,C 語言相對不適合作為初學「演算法」的練習工具。原因在於,開發者必須先手動實作底層的資料結構,才能在其上運行演算法。這種雙層抽象的建構過程,往往會大幅增加除錯的難度。因此,若要專注於演算法練習,更推薦使用具備豐富標準函式庫(STL)的 C++。
在實務開發中,理解 C ABI (Application Binary Interface) 是一項必備的硬實力。現今幾乎所有高階語言的跨語言綁定(Binding)與底層呼叫,都是基於 C ABI 進行溝通。只要掌握了 C ABI 的運作原理,未來在學習其他語言時,剩下的就只是語法表象的差異,能大幅縮短學習遷移的時間。
不過,現今的軟體工程已不再推薦完全使用 C 語言從零開始建構應用程式。這不僅意味著需要徒手打造大量基礎組件、處理繁瑣的字串操作,還必須承擔手動管理記憶體與系統資源的風險。除非是在資源極度受限的特定嵌入式環境(Embedded Systems)下,否則不建議採取這種開發模式。
C 語言是高階語言還是低階語言?
結論先說:C 語言是不折不扣的高階語言。
所謂的「低階語言」,通常特指組合語言(Assembly Language)。組合語言直接對應處理器(CPU)的指令集(Instruction Set),幾乎是以一對一的方式精準控制硬體暫存器。這導致不同架構的處理器(例如 x86 與 ARM)之間的組語無法互通,完全不具備跨平台能力。
C 語言的運作邏輯則截然不同。C 的原始碼必須經由編譯器(Compiler)翻譯成組合語言,最終再轉為機器碼(Machine Code)才能執行。其語法結構並不直接綁定任何特定處理器的指令集,這賦予了它強大的跨平台特性,因此在電腦科學的定義上被歸類為高階語言。
坊間有時會將 C 語言戲稱為「中階語言」或「高階語言的低階」,但這在學術上並非嚴格的分類。C 語言本質上仍是高階語言,只是它的抽象程度較低。許多在現代高階語言(如 Python、Java)中內建的語法特性,在 C 語言中通常被剝離,轉由標準函式庫提供,甚至需要開發者自行實作。
跨平台
C 語言最初是為了撰寫 Unix 系統而設計。當 Unix 以 C 語言重新實作後,系統的可攜性大幅提升:在移植到新硬體時,只需重寫少部分與處理器相關的組合語言,其餘以 C 撰寫的程式碼可以直接重用。
不過,C 的跨平台並不像 Java、Golang 等語言那樣自動化。C 程式需要直接面對各平台的系統 API 差異。除了語法與標準函式庫層級的可攜性之外,實務上仍需由程式設計者主動設計與抽象,才能寫出真正可跨平台的程式。
C 語言的演進
有些人以為 C 語言是老古板,但其實 C 語言仍在持續演化。我們這裡會簡介到西元 2026 年為止的 C 標準演進過程。
K&R C
K&R C 是 C 語言尚未標準化前的非正式標準。該規格記載在 Brian Kernighan 和 Dennis Ritchie 所著的 C 語言經典教材 The C Programming Language 第一版中。由於 C 語言已經標準化了,不需再刻意追隨這個版本的 C 語言。
C89 或 ANSI C
C89 是第一個正式的 C 標準,許多人對 C 語言的印象就是基於這個版本的 C。由於絕大部分的 C 編譯器至少都支援 C89,有些很在意程式碼可攜性的軟體專案會刻意守在這個版本,像是 Lua。
C99
C99 是第一個 C 標準的重大改版,加入許多新的功能。包括但不限於:
- 新增布林數 (boolean)
- 新增複數 (complex number)
- 新增
long long整數 - 新增以
//開頭的單行註解 - 可在
for迴圈內初始化變數 - 可用自動變數決定陣列長度
- 新增一些函式庫
如果沒寫過 C 程式碼,可能會無法理解這些特性。先大略看過,學一陣子 C 語言自然會了解。
大抵上,C99 相容於 C89,但新增一些功能。
C11
C11 是第二個 C 標準的重大改版,加入許多新的功能。包括但不限於:
- 新增型別安全的泛型程式,使用
_Generic保留字 - 支援多執行緒程式
- 加入更多浮點數運算相關的巨集 (macro)
- 支援匿名結構體 (structure) 和匿名聯合 (union)
- 改善對 Unicode 的支援
同樣地,C11 大抵上相容於先前的 C 標準。
現代 C 語言 (modern C) 是指充份利用 C99 和 C11 的特性來撰寫 C 程式碼,不用刻意守在 ANSI C。善用現代 C 語言所帶來的特性,會讓程式碼更簡潔易讀。除非專案需要守在 ANSI C 或是所用的編譯器無法充分支援現代 C 語言的特性,我們應該善用現代 C 語言所帶來的便利性。
C17 或 C18
C18 是一個小改版,沒有引入新的語法特性,僅修復一些先前的問題。
C23
C23(開發期稱為 C2x)是目前最新的 C 語言官方標準。這個版本大幅現代化了語法,引入了如 nullptr、auto 型別推導以及全新的 #embed 預處理指令等實用特性。目前主流編譯器(如 GCC 15 與 Clang)皆已陸續實現完整支援,在開發新專案時,已經可以放心將其作為首選的編譯標準。
Embedded C
初學 C 語言時,會預設 C 程式在個人電腦上運行。相對來說,embedded C 是用於嵌入式裝置的 C 標準,和一般 C 語言有些差異。剛學 C 語言時不用刻意學這套標準,等到熟悉 C 語言後再學也不遲。
POSIX
POSIX 不是 C 標準,而是 Unix 系統的標準,用於 BSD、GNU/Linux 等系統。POSIX 中即定義了一套共通的 C API,所以 C 程式碼在不同類 Unix 系統間是可攜的。由於 GNU/Linux 等類 Unix 系統相當普遍,所以 POSIX 值得關注。
主要的 C 語言編譯器
語言規格只是一份技術文件,實際能否使用,取決於編譯器是否支援。
目前常見的 C 編譯器包括 Visual C++、GCC 與 Clang。各編譯器對標準的支援情況可能隨版本變動,實務上仍應以官方文件為準。
Visual C++
Visual C++ 是隨附於 Visual Studio 的 C/C++ 編譯器,提供完整的開發環境。由於安裝與使用門檻較低,是許多初學者在 Windows 上學習 C 語言時的常見選擇。
GCC
GCC 是 GNU/Linux 等類 Unix 系統常見的編譯器,也有移植到其他平台。GCC 對 C 標準支援完整,並允許透過參數指定不同標準版本。
此外,GCC 提供部分非標準的語言延伸(extensions)。這些特性可提升表達能力,但會降低程式碼的可攜性。
Clang
Clang 是另一套常見的 C/C++ 編譯器,廣泛用於 macOS,也支援多種平台。其設計與 GCC 具有一定程度的相容性。
在學習階段,Clang 通常提供較清楚的錯誤訊息,有助於理解與除錯。
其他 C 語言編譯器
除了通用型編譯器外,也有針對特定用途或硬體設計的工具。
Intel C++ Compiler
Intel 提供的編譯器著重於效能最佳化,特別是在 Intel 處理器上。這類工具多用於效能敏感的應用場景,對初學者而言並非必要。
CUDA
CUDA 是利用 NVIDIA 顯示卡進行平行運算的技術,並在 C 語言上加入延伸語法。由於需依賴特定硬體與非標準特性,通常不作為入門學習工具。
Arduino
Arduino 是常見的嵌入式開發平台,使用接近 C/C++ 的語法撰寫程式。不過其語言環境與標準 C 存在差異,通常在特定應用情境下才會接觸。
和 C 語言相關的程式語言
C 語言簡潔的設計影響了許多後續的程式語言。其中有些語言直接建立在 C 之上,例如 C++ 和 Objective-C,並在此基礎上加入物件系統等較高階的抽象。
C++ 在語言本身中整合了物件導向、泛型等特性,發展成一門規模龐大的語言。雖然語法上與 C 有高度相似性,但兩者已經是不同的語言,也不再存在嚴格的包含關係。
Objective-C 則是在 C 的基礎上加入物件導向機制,主要應用於 Apple 生態系(macOS、iOS)。隨著 Swift 的出現,其重要性已逐漸下降,但在既有系統中仍然被廣泛使用。
本系列文章的記述方式
對於完整的 C 程式碼,會以語法高亮來輔助閱讀:
#include <stdio>
int main (void)
{
printf("Hello World\n");
return 0;
}
同樣地,對於 C 程式碼片段,也會以語法高亮來輔助閱讀:
/* Excerpt */
assert(0 != strcmp("hello", "goodbye"));
Unix (含 macOS、GNU/Linux、FreeBSD 等) 終端機會以 $ 符號來表示指令提示符:
$ cd path/to/project
當使用 root 操作 Unix 終端機時,則會改用 # 來表示指令提示符:
# apt install gcc
Windows 終端機會以 > 來表示指令提示符。為了簡化,不顯示工作目錄:
> cd path\to\project