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]

參考資料

延伸閱讀

外部連結

Wikiwand in your browser!

Seamless Wikipedia browsing. On steroids.

Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.

Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.