C 語言（英語：C Language）是一種通用的、程序式程式設計程式語言，支援結構化程式設計、詞法作用域和遞迴，使用靜態型別系統，並且廣泛用於系統軟體與應用軟體的開發。 C 語言於 1969 年至 1973 年間，為了移植與開發 UNIX 作業系統，由丹尼斯裡奇與肯湯普遜，以 B 語言為基礎，在貝爾實驗室設計、開發出來。二十世紀八十年代，C 語言應用日漸廣泛。為了避免各開發廠商用的 C 語言的語法產生差異，美國國家標準局為 C 語言訂定了一套完整的國際標準語法，稱為 ANSI C，作為 C 語言的標準。與此同時，國際標準化組織也接受該標準為國際標準。因此，ANSI C 也同時被稱為 ISO C。二十世紀八十年代至今的有關程式開發工具，一般都支援符合 ANSI C 的語法。 C 語言具有高效、靈活、功能豐富、表達力強和較高的可移植性等特點，在程式設計中備受青睞，成為最近 25 年使用最為廣泛的程式語言。目前，C 語言編譯器普遍存在於各種不同的作業系統中，例如 Microsoft Windows、macOS、Linux、Unix 等。C 語言的設計影響了眾多後來的程式語言，例如 C、ObjectiveC、Java、C 等。現行的許多軟體都是由 C 語言或者其影響和衍生的程式語言開發出來的。 概述 與 ALGOL 一族的大多數程序式程式設計語言類似，C 語言是一個有結構化程式設計、具有變數作用域（variable scope）以及遞迴功能的程式式語言。其採用的靜態型別系統可以防止無意的程式設計操作。C 語言中所有的可執行程式碼都被包含在子程式（函式）裡。其傳遞引數均是以值傳遞（pass by value），另外也可以傳遞指標（a pointer passed by value）。C 語言是自由形式語言，即其原始碼的縮排並不影響程式的功能，而是使用分號作為語句的結尾，花括號來表示程式碼塊。 由於 C 語言的語言規模較小，若干高層的機制需要使用定義的函式來提供。比如，C 語言並沒有直接處理複合物件（例如字串、集合、列表、陣列等）的操作，也沒有對於儲存器分配工具和記憶體回收工具的直接定義，同時也本身不具有輸入和輸出以及檔案訪問的方法。然而，使用者定義的函式和 C 語言標準庫中的函式為這些高層的機制提供了可能性。 C 語言也具有以下的特性： 基本資料型別包括字元、整型和浮點數等。另外也有派生的各種資料型別，如指標、陣列、結構和聯合。 部份的變數型別可以轉換，例如整數型和字元型變數。 透過指標（pointer），C 語言可以容易的對記憶體進行低階控制。 不同的變數型別可以用結構體（struct）組合在一起。 具有基本的控制流：語句組、條件判斷、多路選擇、迴圈等。 函式可以返回各種資料型別的值，並且都可以遞迴呼叫。每次呼叫函式會重新建立變數。 C 語言只有 32 個保留字（reserved keywords），使變數、函式命名有更多彈性。 編譯預處理（preprocessor）讓 C 語言的編譯更具有彈性。 歷史 20 世紀 70 年代，肯湯姆森為了使其設計的 Unix 系統更加高效，使用 B 語言的變種（即 C 語言）在 DEC PDP7 計算機上重寫了 Unix。C 語言中許多重要概念來源於 BCPL 語言，其對 C 語言的影響也間接地來源於 B 語言。在 1978 年，丹尼斯裡奇和布萊恩柯林漢合作出版了《C 程式設計語言》第一版，事實上即為 KR C 標準 。1983 年，為了制定一個獨立於具體機器且無歧義的 C 語言標準，美國國家標準協會成立了一個委員會，並在 1988 年完成了該標準的制定，即 ANSI C。此標準同時被國際標準化組織所採納，也被稱作 ISO C。 其後，C 語言至今經歷了幾次標準更新，誕生了 C99、C11 和目前最新的標準 C18。C 語言標準的下一次更新 C2x 目前正在起草中。 語法 C 語言的語法相對簡潔而直接。C 語言的形式文法由國際標準化組織所制定。簡單來說，C 語言包括如下文法： 作為一種指令式程式語言，C 語言使用語句執行操作。最常見的語句是表示式語句，由一個表示式後加一個分號組成，可以令系統呼叫函式和為變數賦值； 註釋： C 語言支援單行註釋（以 開頭）和多行註釋（以 開始，以 結束）； 資料型別： 基本的資料型別包括整數（int）、浮點數（float 和 double）、字元（char）、列舉 enum 等； 陣列： 陣列是一組相同型別的資料元素的集合。使用以下方法初始化一個五個元素的整數陣列： int numbers 5 1 2 3 4 5 封裝結構：結構（struct）、聯合（union）； 結構化程式設計和控制結構： C 語言包括條件語句（if、else）、迴圈語句（for、while、dowhile）等； 跳轉語句：C 語言允許使用跳轉關鍵字 goto、break 和 continue 來實現程式塊之間的跳轉，這和匯編語言的 jmp 關鍵字有一定相似處； 函式： C 語言中的函式是程式的基本模組，可以自定義函式並在程式中呼叫； 靈活且靠近底層的記憶體控制機制：C 程式設計師可以自由選擇分配何種記憶體，以及分配多大的記憶體，如如下程式碼所示： int array int malloc 5 sizeof int 分配一個包含五個整數的陣列 free array 釋放使用 malloc 分配的記憶體 Hello World 程式 現在廣泛被程式設計初學者使用的 hello world 程式例項最初就是出現在《C 程式設計語言》第一版中。下面是一個在標準輸出裝置（stdout）上打印出 Hello world 字串的簡單程式。類似的程式，通常作為初學程式語言時的第一個程式： include stdioh int main void printf Hello worldn return 0 其中只有 int，void，return 為 C 語言的關鍵字，預處理器會將 include stdioh 替換為 stdioh 檔案的內容。 main 函式是 C 語言程式的入口點。 Hello worldn 中的 n 是一個跳脫字元，形式為 加上一個字元。所起的作用在 ASCII 碼中規定。 printf 是聲明於 stdioh 的函式，關於 printf 的更多細節，參見 printf； 關於格式化字串的更多資訊，參見格式化字串。 記憶體管理 C 語言的特色之一是：程式設計師必須親自處理記憶體的分配細節。語言不負責記憶體邊界檢查，這是因為在執行時進行記憶體邊界檢查會造成效能問題，與 UNIX 哲學不符。此特性容易導致緩衝區溢位問題。然而，部分編譯器（如英特爾編譯器）會出於安全性的考量，提供方法以進行執行時記憶體邊界檢查。 大多數 C 語言實現使用棧（Stack）來儲存函式返回地址／棧幀基址、完成函式的引數傳遞和函式區域性變數的儲存。然而，在部分極特殊的平臺上，使用棧並不能獲得最大效率。此時的實現由編譯器決定。 如果程式需要在執行的過程中動態分配記憶體，可以利用堆（Heap）來實現。 基本上 C 程式的元素儲存在記憶體的時候有 3 種分配策略： 靜態分配 如果一個變數宣告為全域性變數或者是函式的靜態變數，這個變數的儲存將使用靜態分配方式。靜態分配的記憶體一般會被編譯器放在資料段或程式碼段來儲存，具體取決於實現。這樣做的前提是，在編譯時就必須確定變數的大小。 以 IA32 的 x86 平臺及 gcc 編譯器為例，全域性及靜態變數放在資料段的低端；全域性及靜態常量放在程式碼段的高階。 自動分配 函式的自動區域性變數應該隨著函式的返回會自動釋放（失效），這個要求在一般的體系中都是利用棧（Stack）來滿足的。相比於靜態分配，這時候，就不必絕對要求這個變數在編譯時就必須確定變數的大小，執行時才決定也不遲，但是 C89 仍然要求在編譯時就要確定，而 C99 放鬆了這個限制。但無論是 C89 還是 C99，都不允許一個已經分配的自動變數執行時改變大小。 所以說 C 函式永遠不應該返回一個區域性變數的地址。 要指出的是，自動分配也屬於動態分配，甚至可以用 alloca 函式來像分配堆（Heap）一樣進行分配，而且釋放是自動的。 動態分配 還有一種更加特殊的情況，變數的大小在執行時有可能改變，或者雖然單個變數大小不變，變數的數目卻有很大彈性，不能靜態分配或者自動分配，這時候可以使用堆（Heap）來滿足要求。ANSI C 定義的堆操作函式是 malloc、calloc、realloc 和 free。 使用堆（Heap）記憶體將帶來額外的開銷和風險。 庫 C 語言的標準文件要求了一個平臺移植 C 語言的時候至少要實現的一些功能和封裝的集合，稱為 標準庫，標準庫的宣告頭部透過預處理器命令 include 進行引用。 在 C89 標準中： 檔案 簡介說明 asserth 斷言相關 ctypeh 字元型別判斷 errnoh 標準報錯機制 floath 浮點運算 limitsh 各種體系結構限制 localeh 本地化介面 mathh 數學函式 setjmph 跨函式跳轉 signalh 訊號（類似 UNIX 的訊號定義，但是差很遠） stdargh 可變參處理 stddefh 一些標準宏定義 stdioh 標準 IO 庫 stdlibh 標準工具庫函式 stringh ASCII 字串及任意記憶體處理函式 時間相關 在 94 年的修正版中 iso646h wcharh wctypeh 在 C99 中增加了六個函式庫 complexh fenvh inttypesh stdboolh stdinth tgmathh 以上是 C 語言的標準。各個系統各自又對 C 庫函式進行的各種擴充，就浩如煙海了。如 POSIX C、GNU C 等。 工具軟體 工具軟體可以幫助程式設計者避免一些程式中潛藏或容易出現的問題，例如常會造成程式未預期動作或是執行期錯誤的程式碼。 許多語言都有自動原始碼檢查及審計工具，C 語言也有類似工具，像是 Lint。可以在程式剛寫好時用 Lint 找出可能有問題的程式，透過 Lint 後再用 C 編譯器進行編譯，許多編譯器也可以設定是否要針對一些可能有問題的程式碼提出警告。MISRA C 是一套針對嵌入式系統的法則，可主要也是避免一些可能有問題的程式碼。 也有一些編譯器、程式庫或作業系統可以處理一些非標準 C 語言的功能，例如邊界值檢查、快取溢位偵測、序列化及自動垃圾回收功能。 使用像 Valgrind 或等軟體工具，或者連結有特別 malloc 函式的程式庫，有助於找出一些執行期記憶體使用的問題。 經典錯誤 void main 的用法並不是任何標準制定的 Can I write void main The definition void main is not and never has been C nor has it even been C。 C 語言標準語法是 int main ，任何實現都必須支援 int main void 和 int main int argc char argv 「The function called at program startup is named main The implementation declares no prototype for this function It shall be defined with a return type of int and with no parameters int main void or with two parameters referred to here as argc and argv though any names may be used as they are local to the function in which they are declared int main int argc char argv or equivalent or in some other implementationdefined manner」，引自 ISOIEC 98991999 Section 51221 Program startup。 在 C 標準中，main 的標準型態應是 int，否則型別是由實現定義的。任何實現都必須支援 int main 和 int main int argc char argv 「An implementation shall not predefine the main function This function shall not be overloaded It shall have a return type of type int but otherwise its type is implementationdefined All implementations shall allow both of the following definitions of main int main and int main int argc char argv 」，引自 ISOIEC 14882 第一版 1998、第二版 2003 與第三版 2011 section 361 Main function。 參見 塊 C 語言擴充套件 註腳 註解 參考資料 參考資料 外部連結 Coding Programmer Page C Library Reference and Examples english GCC 首頁 GLIBC2 首頁 Visual Studio Express 首頁 ISOIEC 9899。C99 標準的官方網站。目前（2020 年）可直接下載的標準文字是 ISOIEC 9899202x。 CategoryC 語言家族 Category 美國發明 Category 跨平臺軟體 Category 程序式程式設計語言 Category 靜態型別程式語言 Category 系統程式語言 CategoryISO 標準化程式語言 Category1972 年建立的程式語言