複製鏈接
請複製以下鏈接發送給好友

C11

鎖定
C11標準ISO/IEC 9899:2011 - Information technology -- Programming languages -- C 的簡稱 [1]  ,曾用名為C1X。
C11標準是C語言標準的第三版,前一個標準版本是C99標準。2011年12月8日,國際標準化組織(ISO)和國際電工委員會(IEC) 旗下的C語言標準委員會(ISO/IEC JTC1/SC22/WG14)正式發佈了C11標準 [2] 
C11標準的最終定稿的草案免費開放的,為N1570 [3]  ,但是正式標準文件需要198瑞士法郎 [2] 
當前,支持此標準的主流C語言編譯器有:GCCClangIntel C++ Compiler等。
中文名
C11
外文名
C11
曾用名
C1X
標準編號
ISO/IEC 9899:2011
發佈時間
2011年12月8日
發佈機構
ISO/IEC JTC1/SC22/WG14

C11相比C99的變化

1. 對齊處理操作符 alignof,函數 aligned_alloc(),以及 頭文件 <stdalign.h>。見 7.15 節。
2. _Noreturn 函數標記,類似於 gcc 的 __attribute__((noreturn))。例子:
_Noreturn void thrd_exit(int res);
3. _Generic 關鍵詞,有點兒類似於 gcc 的 typeof。示例代碼:
#include<stdio.h>



#define GENERAL_ABS(x)_Generic((x),int:abs,float:fabsf,double:fabs)(x)



int main(void)
{

    printf("intabs:%d\n",GENERAL_ABS(-12));
    
    printf("floatabs:%f\n",GENERAL_ABS(-12.04f));
    
    printf("doubleabs:%f\n",GENERAL_ABS(-13.09876));
    
    
    
    int a=10;
    
    int b=0,c=0;
    
    
    _Generic(a+0.1f,int:b,float:c,default:b)++;
    
    printf("b=%d,c=%d\n",b,c);
    
    
    
    _Generic(a+=1.1f,int:b,float:c,default:b)++;
    
    printf("a=%d,b=%d,c=%d\n",a,b,c);

}

4. 靜態斷言( static assertions),_Static_assert(),在解釋 #if 和 #error 之後被處理。例子:
_Static_assert(FOO > 0, "FOO has a wrong value");
5. 刪除了 gets() 函數,C99中已經將此函數被標記為過時,推薦新的替代函數 gets_s()。
6. 新的 fopen() 模式,(“…x”)。類似 POSIX 中的 O_CREAT|O_EXCL,在文件鎖中比較常用。
7. 匿名結構體/聯合體,這個早已經在 gcc 中了,我們並不陌生,定義在 6.7.2.1 p13。
8. 多線程支持,包括:_Thread_local,頭文件 <threads.h>,裏面包含線程的創建和管理函數(比如 thrd_create(),thrd_exit()),mutex (比如 mtx_lock(),mtx_unlock())等等,更多內容清參考 7.26 節。
9. _Atomic類型修飾符和 頭文件 <stdatomic.h>,見 7.17 節。
10. 帶邊界檢查(Bounds-checking)的函數接口,定義了新的安全的函數,例如 fopen_s(),strcat_s() 等等。更多參考 Annex K。
11. 改進的 Unicode 支持,新的頭文件 <uchar.h> 等。實例代碼:
#include<stdio.h>
#include<uchar.h>

size_t UTF16StrLen(const char16_t *utf16String)
{
    if(utf16String==NULL)
    return0;
    
    size_t index;
    for(index=0;utf16String[index]!=u'\0';index++);
        returnindex;
}

size_t UTF16ToUTF8(char *mbBuffer,const char16_t *utf16String)
{
    if(mbBuffer==NULL||utf16String==NULL)
    return 0;

    mbstate_t state={};

    size_t mbIndex=0;
    for(int utf16Index=0;utf16String[utf16Index]!=u'\0';utf16Index++)
    {
        constsize_tlength=c16rtomb(&mbBuffer[mbIndex],utf16String[utf16Index],&state);
        mbIndex+=length;
    } 

    mbBuffer[mbIndex]='\0';
    
    return mbIndex;
}

int main(int argc,char *argv[])
{
    char16_t ch=u'好';
    char chBuffer[64];
    mbstate_t state={};
    
    size_t length=c16rtomb(chBuffer,ch,&state);
    chBuffer[length]='\0';
    
    printf("TheUTF-8characterlengthis:%zu,andthecharacteris:%s\n",length,chBuffer);
    
    const char * utf8Str=u8"你好,世界。";
    printf("TheUTF-8stringis:%s\n",utf8Str);
    
    const char16_t *utf16Str=u"你好,世界。";
    printf("Theutf16stringlengthis:%zu\n",UTF16StrLen(utf16Str));

    length=UTF16ToUTF8(chBuffer,utf16Str);
    
    printf("TheUTF-8stringlengthis:%zu,andthecontentis:%s\n",length,chBuffer);
    
    printf("IftheconvertedUTF-8stringisequaltotheoriginalone?%s\n",strcmp(chBuffer,utf8Str)==0?"YES":"NO");
}
12. 新增 quick_exit() 函數,作為第三種終止程序的方式,當 exit() 失敗時可以做最少的清理工作(deinitializition),具體見 7.22.4.7。
13. 創建複數的宏, CMPLX(),見 7.3.9.3。
14. 更多浮點數處理的宏 (More macros for querying the characteristics of floating point types, concerning subnormal floating point numbers and the number of decimal digits the type is able to store)。
15. struct timespec 成為 time.h 的一部分,以及宏 TIME_UTC,函數 timespec_get()。

C11C11還缺少什麼

1、對IEEE754標準-2008的半精度浮點數的支持。儘管遵循GNU C標準規範的編譯器GCC以及Clang等)使用了C擴展關鍵字__fp16,但是隻能對半精度浮點數進行引用,而不能做任何算術操作。因此,這個特性應當在下一個C語言標準中立馬加入進去的,建議使用_Half作為半精度浮點數類型的關鍵字。
2、匿名函數:匿名函數,也叫lambda表達式,是現代計算機編程語言的一個典範特性,在Clang編譯器中已經通過blocks語法 [4]  進行了支持,該語法也被髮表到了下一代C標準的提案 [5-6] Lambda表達式非常適用於多核多線程並行計算,而不僅僅只是用於語法糖
3、增加對UTF-16字符編碼字符串格式符的支持。在標準C語言中,直到C11還只能支持UTF-8編碼字符串的格式,採用%s。而對於UTF-16編碼字符串的各類操作都比較欠缺,而只有UTF-16轉UTF-8的庫函數c16rtomb以及UTF-8轉UTF-16的標準庫函數mbrtoc16可使用,因此在實際項目工程上,用起來十分繁瑣。這裏建議後續標準C語言採用%S表示UTF-16的字符串格式符,%s作為UTF-8字符串格式符,%C表示UTF-16字符,%c表示UTF-8字符。
參考資料