C99

C程式語言標準的版本

C99(之前名稱為C9X)是ISO/IEC 9899:1999的非正式名稱,是C語言標準的一個版本[1]。C99延伸了C90的內容,加入了C語言及標準函式庫的新功能,讓一些語言的實現(例如IEEE 754-1985英語IEEE_754-1985浮點數,以及編譯器技術)可以更妥善的利用電腦的硬體[2]。後來在2011年發行的C11取代了此版本的C語言標準。

歷史

編輯

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

設計

編輯

在C99中包括的特性有:

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

版本檢測

編輯

標準宏__STDC_VERSION__被定義為值199901L來指示能夠獲得C99支援。就像__STDC__宏用於C90,__STDC_VERSION__可被用來書寫對於C90和C99編譯器進行不同編譯的代碼,下面的例子確保了inline在二者情況下都可獲得(通過在C90中將其替代為static來避免連接器錯誤):

#if __STDC_VERSION__ >= 199901L
  /* "inline" is a keyword */
#else
# define inline static
#endif

實現

編輯

用於x86架構GCC,Clang和其它一些商業編譯器(如IAR Systems,ICC)現支援C99的全部特性[4],而微軟Borland支援C99的部分特性[5]

參考資料

編輯
  1. ^ ISO/IEC 9899:1999 - Programming languages - C. Iso.org. 2011-12-08 [2014-04-08]. (原始內容存檔於2016-10-10). 
  2. ^ 存档副本 (PDF). [2020-07-03]. (原始內容存檔 (PDF)於2017-06-22). 
  3. ^ ISO/IEC 9899:1999 (PDF). [2020-06-10]. (原始內容存檔 (PDF)於2018-01-27). 
  4. ^ GCC從3.0版本開始正式支援C99(-std=c99),詳情見
  5. ^ Peter Bright. C99 acknowledged at last as Microsoft lays out its path to C++14. Ars Technica. 29 June 2013 [9 January 2015]. (原始內容存檔於2020-07-02). 

延伸閱讀

編輯

外部連結

編輯
前任者:
C89 / C90 / "ANSI C"
C語言標準 繼任者:
C11