跳到主要內容
:::

教育百科logo

::: C語言 - 教育百科

詞條名稱:C語言


教育Wiki


C語言,是一種通用的、程序式的程式語言,廣泛用於系統與應用軟體的開發。具有高效、靈活、功能豐富、表達力強和較高的移植性等特點,在程式設計師中備受青睞。最近25年是使用最為廣泛的程式語言。

C語言是由UNIX的研製者丹尼斯·里奇(Dennis Ritchie)於1970年由 肯·湯普遜(Ken Thompson)所研製出的B語言的基礎上發展和完善起來的。

目前,C語言編譯器普遍存在於各種不同的作業系統中,例如UNIX、MS-DOS、Microsoft Windows及Linux等。

C語言的設計影響了許多後來的程式語言,例如C++、Objective-C、Java、C#等。

1980年代,為了避免各開發廠商用的C語言語法產生差異,由美國國家標準局(American National Standard Institution)為C語言訂定了一套完整的國際標準語法,稱為ANSI C,作為C語言的標準。

1980年代至今的有關程式開發工具,一般都支援符合ANSI C的語法。

目錄

設計哲學

C語言是一個程式語言,設計目標是提供一種能以簡易的方式編譯、處理低階記憶體、產生少量的機器碼以及不需要任何執行環境支援便能執行的程式語言。C語言也很適合搭配組合語言來使用。儘管C語言提供了許多低階處理的功能,但仍然保持著良好跨平台的特性,以一個標準規格寫出的C語言程式可在許多電腦平台上進行編譯,甚至包含一些嵌入式處理器(微控制器或稱MCU)以及超級電腦等作業平台。

特色

  1. C語言是一個有結構化程式設計、具有變數作用域(variable scope)以及遞迴功能的程序式語言。
  2. 傳遞參數是以值傳遞(Pass-by-value),也可以透過指標來傳遞參數(Pass-by-address)。
  3. 不同的變數類型可以用結構體(struct)組合在一起。
  4. 只有32個保留字(reserved keywords),使變數、函式命名有更多彈性。
  5. 部份的變數類型可以轉換,例如整型和字元型變數。
  6. 透過指標(pointer),C語言可以容易的對記憶體進行低階控制。
  7. 編譯預處理(preprocessor)讓C語言的編譯更具有彈性。

歷史

早期發展

C語言最早是由丹尼斯·里奇為了在PDP-11電腦上執行的UNIX系統所設計出來的程式語言,第一次發展在1969年到1973年之間。之所以被稱為「C」是因為C語言的很多特性是由一種更早的被稱為B語言的程式語言中發展而來。早期作業系統的核心大多由組合語言組成,隨著C語言的發展,C語言已經可以用來編寫作業系統的核心。1973年,Unix作業系統的核心正式用C語言改寫,這是C語言第一次應用在作業系統的核心編寫上。

K&R C

1978年,丹尼斯·里奇(Dennis Ritchie)和布萊恩·柯林漢(Brian Kernighan)合作出版了《C程式語言》的第一版。書中介紹的C語言標準也被C語言程式設計師稱作「K&R C」,第二版的書中也包含了一些ANSI C的標準。K&R C主要介紹了以下特色:


  1. 結構(struct)型別
  2. 長整數(long int)型別
  3. 無號整數(unsigned int)型別
  4. 把運算子=+和=-改為+=和-=。因為=+和=-會使得編譯器不知道使用者要處理i = -10還是i =- 10,使得處理上產生混淆。


即使在後來ANSI C標準被提出的許多年後,K&R C仍然是許多編譯器的最低標準要求,許多老舊的編譯仍然執行K&R C的標準。

ANSI C 和 ISO C

1989年,C語言被 ANSI 標準化(ANSI X3.159-1989)。標準化的一個目的是擴充功能K&R C。這個標準包括了一些新特性。在K&R出版後,一些新特性被非官方地加到C語言中。

  1. void 函式
  2. 函式返回 struct 或 union 型別
  3. void * 資料型別

在ANSI標準化自己的過程中,一些新的特性被加了進去。ANSI也規定了一套標準函式庫。ANSI ISO(國際標準化組織)成立 ISO/IEC JTC1/SC22/WG14 工作群組,來規定國際標準的C語言。透過對ANSI標準的少量修改,最終透過了 ISO 9899:1990。隨後,ISO標準被 ANSI 採納。傳統C語言到ANSI/ISO標準C語言的改進包括:

  1. 增加了真正的標準庫
  2. 新的預處理命令與特性
  3. 函式原型允許在函式申明中指定參數型別
  4. 一些新的關鍵字,包括 const、volatile 與 signed
  5. 寬字元、寬字串與多位元組字元
  6. 對約定規則、宣告和型別檢查的許多小改動與澄清

WG14工作小組之後又於1994年,對1985年頒布的標準做了兩處技術修訂(缺陷修復)和一個補充(擴充功能)。下面是 1994 年做出的所有修改:

  1. 3 個新的標準庫標頭檔 iso646.h、wctype.h 和 wchar.h
  2. 幾個新的記號與預定義巨集,用於對國際化提供更好的支援
  3. printf/sprintf 函式一系列新的格式代碼
  4. 大量的函式和一些型別與常量,用於多位元組字元和寬位元組字元


C99

在ANSI的標準確立後,C語言的規範在一段時間內沒有大的變動,然而C++在自己的標準化建立過程中繼續發展壯大。《標準修正案一》在1994年為C語言建立了一個新標準,但是只修正了一些C89標準中的細節和增加更多更廣的國際字符集支援。不過,這個標準引出了1999年ISO 9899:1999的發表。它通常被稱為C99。C99被ANSI於2000年3月採用。在C99中包括的特性有:

  1. 增加了對編譯器的限制,比如源程式每行要求至少支援到 4095 位元組,變數名函式名的要求支援到 63 位元組(extern 要求支援到 31)。
  2. 增強了預處理功能。例如:
    巨集支援取可變參數 #define Macro(...) __VA_ARGS__
    使用巨集的時候,允許省略參數,被省略的參數會被擴充功能成空串。
    支援 // 開頭的單行注釋(這個特性實際上在C89的很多編譯器上已經被支援了)
  1. 增加了新關鍵字 restrict, inline, _Complex, _Imaginary, _Bool
    支援 long long, long double _Complex, float _Complex 等型別
  1. 支援不定長的陣列,即陣列長度可以在執行時決定,比如利用變數作為陣列長度。宣告時使用 int a[var] 的形式。不過考慮到效率和實作,不定長陣列不能用在全域,或 struct 與 union 里。
  2. 變數宣告不必放在語句塊的開頭,for 語句提倡寫成 for(int i=0;i<100;++i) 的形式,即i 只在 for 語句塊內部有效。
  3. 允許採用(type_name){xx,xx,xx} 類似於 C++ 的建構函式的形式構造匿名的結構體。
  4. 初始化結構的時候允許對特定的元素賦值,形式為:
    struct test{int a[3],b;} foo[] =  { [0].a = {1}, [1].a = 2 };
    struct test{int a, b, c, d;} foo =  { .a = 1, .c = 3, 4, .b = 5}  // 3,4 是對 .c,.d 賦值的
  1. 格式化字串中,利用 \u 支援 unicode 的字元。
  2. 支援 16 進制的浮點數的描述。
  3. printf scanf 的格式化串增加了對 long long int 型別的支援。
  4. 浮點數的內部資料描述支援了新標準,可以使用 #pragma 編譯器指令指定。
  5. 除了已有的 __line__ __file__ 以外,增加了 __func__ 得到當前的函式名。
  6. 允許編譯器化簡非常數的運算式。
  7. 修改了 / % 處理負數時的定義,這樣可以給出明確的結果,例如在C89中-22 / 7 = -3, -22 % 7 = -1,也可以-22 / 7= -4, -22 % 7 = 6。 而C99中明確為 -22 / 7 = -3, -22 % 7 = -1,只有一種結果。
  8. 取消了函式返回型別預設為 int 的規定。
  9. 允許 struct 定義的最後一個陣列不指定其長度,寫做 [](flexible array member)。
  10. const const int i 將被當作 const int i 處理。
  11. 增加和修改了一些標準標頭檔,比如定義 bool 的 <stdbool.h> ,定義一些標準長度的 int 的 <inttypes.h> ,定義複數的 <complex.h> ,定義寬字元的 <wctype.h> ,類似於泛# 型的數學函式 <tgmath.h>, 浮點數相關的 <fenv.h>。 在<stdarg.h> 增加了 va_copy 用於複製 ... 的參數。 里增加了 struct tmx ,對 struct tm 做了擴充功能。
  12. 輸入輸出對寬字元以及長整數等做了相應的支援。
  13. 但是各個公司對C99的支援所表現出來的興趣不同。當GCC和其它一些商業編譯器支援C99的大部分特性的時候[2],微軟和Borland卻似乎對此不感興趣。

C11

2011年12月8日,ISO正式發行了新的C語言的新標準C11,之前被稱為C1X,官方名稱為ISO/IEC 9899:2011。新的標準提高了對C++的相容性,並增加了一些新的特性。這些新特性包括:

  1. 對齊處理(Alignment)的標準化(包括_Alignas標誌符,alignof運算子, aligned_alloc函式以及<stdalign.h>標頭檔。
  2. _Noreturn 函式標記,類似於 gcc 的 __attribute__((noreturn))。
  3. _Generic 關鍵字。
  4. 多執行緒(Multithreading)支援,包括:_Thread_local儲存型別識別元,<threads.h>標頭檔,裡面包含了執行緒的建立和管理函式。
  5. 增強的Unicode的支援。基於C Unicode技術報告ISO/IEC TR 19769:2004,增強了對Unicode的支援。包括為UTF-16/UTF-32編碼增加了char16_t和char32_t資料型別,提供了包含# # unicode字串轉換函式的標頭檔<uchar.h>.
  6. 刪除了 gets() 函式,使用一個新的更安全的函式gets_s()替代。
  7. 增加了邊界檢查函式介面,定義了新的安全的函式,例如 fopen_s(),strcat_s() 等等。
  8. 增加了更多浮點處理巨集。
  9. 匿名結構體/聯合體支援。這個在gcc早已存在,C11將其引入標準。
  10. 靜態斷言(Static assertions),_Static_assert(),在解釋 #if 和 #error 之後被處理。
  11. 新的 fopen() 模式,(「…x」)。類似 POSIX 中的 O_CREAT|O_EXCL,在档鎖中比較常用。
  12. 新增 quick_exit() 函式作為第三種終止程式的方式。當 exit()失敗時可以做最少的清理工作。
  13. _Atomic型別修飾詞和<stdatomic.h>標頭檔。
回到頁面頂端圖示