C 語言 99, 11 新政策

1. C99

已經(jīng)是上個世紀的最后一版 C 語言,但由于譚浩強當年沒有跟上趋厉,導致我們很多人也沒跟上。

1.1. 語法級

1.1.1. 基本概念

1.1.1.1. 注釋

C99 起支持 C++ 式的雙斜杠單行注釋。

1.1.1.2. 標識符

標識符中可使用由 \u\U 轉(zhuǎn)義的 Unicode 字符逾条。\u 后面為 4 位 16 進制數(shù),\U 后面為 8 位 16 進制數(shù)投剥,該 16 進制數(shù)表示一個 Unicode 碼點师脂,如:

int \u6211 = 42;

1.1.2. 預處理

1.1.2.1. 宏

1.1.2.1.1. 宏定義

#define 指令的形參列表尾部可使用變長參數(shù)列表 ...,使用 __VA_ARGS__ 訪問變長參數(shù),如:

#define print1(s, ...) printf(s, 1, __VA_ARGS__)

print1("%d %d %d\n", 2, 3); // printf("%d %d %d\n", 1, 2, 3);

使用 #__VA_ARGS__ 將變長參數(shù)放入一對雙引號中危彩,并用一個逗號與空格隔開(無論代碼如何排版)攒磨,如:

#define print2(a, b, ...) printf(#__VA_ARGS__, a, b)

print2(1, 2, %d,
    %d); // printf("%d, %d", 1, 2);

1.1.2.1.2. 預定義宏

__STDC_VERSION__ 的值為 199901L

新增宏 __STDC_HOSTED__汤徽,當目標環(huán)境為操作系統(tǒng)之下則為 1娩缰,目標環(huán)境無操作系統(tǒng)則為 0

1.1.3. 表達式

1.1.3.1. 字面量

新增整型字面量后綴 llLL谒府,表示 long long 類型拼坎。新增整型字面量后綴 ullUlluLLULL,表示 unsigned long long 類型完疫。

新增字符字面量轉(zhuǎn)義符 \u\U泰鸡。\u 后面為 4 位 16 進制數(shù),\U 后面為 8 位 16 進制數(shù)壳鹤,該 16 進制數(shù)表示一個 Unicode 碼點盛龄,如 '\u6211'

新增復合字面量用以表達數(shù)組芳誓、結(jié)構(gòu)體余舶、聯(lián)合體,其形式為 (類型){初始化列表}锹淌,如:

int i = (int[]){ 1, 2 }[1];

1.1.3.2. 初始化

初始化列表中的項匿值,新增一種可用形式 指派器列表=初始化器。其中指派器列表的形式為數(shù)組的下標表達式 [常量表達式] 或結(jié)構(gòu)體赂摆、聯(lián)合體的成員訪問表達式 .標識符挟憔。

對于數(shù)組的初始化,可使用指派器列表指定下標烟号,后續(xù)的下標會在此指定值的基礎上依次加 1绊谭,如:

int ar[5] = { 1, [4] = 5, [1] = 2, 3 }; // { 1, 2, 3, 0, 5 }

按照初始化列表的順序,后面相同下標的賦值會覆蓋前面汪拥,如:

int ar[5] = { [3] = 5, 5, [1] = 2, 3, 4 }; // { 0, 2, 3, 4, 5 }

可用于嵌套數(shù)組龙誊,此時指派器列表可以是嵌套的數(shù)組下標表達式,用于指定當前嵌套深度下的數(shù)組下標喷楣,如:

int ar[3][3] = { [0] = { 1, [1] = 2, 3 }, { [1] = 5, 6 }, [2][1] = 8, 9 }; // { { 1, 2, 3 }, { 0, 5, 6 }, { 0, 8, 9 } }

對于結(jié)構(gòu)體的初始化趟大,可使用指派器列表指定成員,后續(xù)的成員會依照結(jié)構(gòu)體中成員聲明的順序铣焊,后面相同成員的賦值會覆蓋前面逊朽,如:

typedef struct S {
    int a, b, c, d, e;
} S;

S s = { 1, 1, .e = 5, .b = 2, 3 }; // { 1, 2, 3, 0, 5 }

可用于嵌套結(jié)構(gòu)體,此時指派器列表可以是嵌套的成員訪問表達式曲伊,用于指定當前嵌套深度下的成員叽讳,如:

typedef struct S {
    int a, b, c;
} S;

typedef struct R {
    S x, y, z;
} R;

R r = { .x = { 1, .b = 2, 3 }, { .b = 5, 6 }, .z.b = 8, 9 }; // { { 1, 2, 3 }, { 0, 5, 6 }, { 0, 8, 9 } }

1.1.4. 聲明

聲明不再限定于只能出現(xiàn)在塊的開頭追他。這是 C99 中譚浩強錯過的最重要的一點,以致于到了二十一世紀我們許多人還遵守著這個限制岛蚤。

1.1.4.1. 限定符

在函數(shù)聲明中邑狸,限定符可用于數(shù)組形參的方括號內(nèi),數(shù)組形參會轉(zhuǎn)化為指針形參涤妒,限定符轉(zhuǎn)而修飾該指針单雾,如:

int f(int[const]); // int f(int* const)
int g(const int[]); // int g(const int*)
1.1.4.1.1. restrict

新增限定符關鍵字 restrict 以修飾一個指針類型的左值,提示編譯器在該指針的作用域內(nèi)她紫,如果經(jīng)由該指針所訪問的內(nèi)存會被修改硅堆,則該內(nèi)存僅經(jīng)由該指針訪問。根據(jù)此限定符贿讹,編譯器能作出更大膽的優(yōu)化渐逃。

1.1.5. 語句

1.1.5.1. for

for 語句的初始化子句可以是一個聲明,該聲明的作用域為整個循環(huán)體民褂,包括循環(huán)體的條件表達式和迭代表達式茄菊,如:

for (int i = 0; i < 42; i++) {

1.1.6. 類型

1.1.6.1. 標量

新增至少 64 位的有符號整型 long long 和無符號整型 unsigned long long

新增算術(shù)類型關鍵字 _Bool赊堪,該類型的值只能是 01面殖。通常使用頭文件 stdbool.h 中定義的宏 booltrue雹食、false畜普。所有非零值的標量轉(zhuǎn)化為 _Bool 類型后其值為 1期丰,零值的標量轉(zhuǎn)化為 _Bool 類型后其值為 0群叶,注意這與轉(zhuǎn)化為其他某種整型時的區(qū)別,特別是將其他某種整型用作布爾類型時钝荡,如:

#include <stdbool.h>

bool b1 = false; // _Bool b1 = 0;
bool b2 = NULL; // 0
bool b3 = 0.5; // 1
#define Bool unsigned char
Bool b4 = 0.5; // 0

1.1.6.2. 數(shù)組

新增變長數(shù)組街立。聲明一個數(shù)組時如果長度不是一個常量,則聲明為變長數(shù)組埠通,如:

void f(int i) {
    int ar[i];

變長數(shù)組的聲明不能使用初始化列表赎离。變長數(shù)組的長度在運行時確定,內(nèi)存在運行時分配端辱,長度在其生命周期內(nèi)不可變梁剔。變長數(shù)組的生命周期只能在函數(shù)塊內(nèi)部,不能作為全局變量舞蔽、結(jié)構(gòu)體和聯(lián)合體的成員荣病。

變長數(shù)組作為函數(shù)形參時,在函數(shù)原型聲明中渗柿,使用 * 作為數(shù)組長度个盆,該數(shù)組同樣會轉(zhuǎn)化為元素類型的指針,如:

void f(int[*]); // void f(int*)

變長組數(shù) T[n]sizeof 操作仍是計算整個數(shù)組的長度,即 sizeof(T) * n颊亮,但是在運行時計算柴梆,因此不再是常量。

1.1.6.3. 枚舉

允許枚舉聲明中的最后一項的后面出現(xiàn)逗號终惑。

1.1.6.4. 結(jié)構(gòu)體

新增結(jié)構(gòu)體柔性數(shù)組成員绍在。柔性數(shù)組成員只能作為不完整數(shù)組類型而聲明在最后,如:

typedef struct S {
    char c;
    int ar[];
} S;

S *s = (S*)malloc(sizeof(S) + sizeof(int) * 3);
s->ar[2] = 42;

結(jié)構(gòu)體的初始化列表狠鸳、sizeof 操作符揣苏、賦值操作符會忽略柔性數(shù)組成員。包含柔性數(shù)組成員的結(jié)構(gòu)體不能作為數(shù)組元素和結(jié)構(gòu)體成員件舵。

結(jié)構(gòu)體位域字段可使用 _Bool 類型卸察,寬度只能為 1,如:

struct S {
    _Bool b: 1;
};

1.1.7. 函數(shù)

新增函數(shù)域內(nèi)的預定義靜態(tài)局部變量 static const char __func__[]铅祸,內(nèi)容為當前函數(shù)名坑质。

1.2. 標準庫級

1.2.1. 類型

頭文件 <stdbool.h>

定義了宏 booltrue临梗、false涡扼。truefalse 是整型常量 10

頭文件 <stdint.h>

定義了確定長度的整型 typedef int8_t盟庞、int16_t吃沪、int32_tint64_t什猖、intptr_t票彪、uint8_tuint16_t不狮、uint32_t降铸、uint64_tuintptr_t 等摇零。

1.2.2. 數(shù)值計算

新增大量數(shù)值計算函數(shù)推掸。

參考文檔

2. C11

和 C++ 同年推出的新世紀第一個 C 語言新標準,譚浩強更加跟不上了驻仅。

2.1. 語法級

2.1.1. 基本概念

2.1.1.1. 對齊

新增操作符關鍵字 _Alignof 查詢類型的對齊谅畅,返回類型為 size_t,返回值為常量噪服,如:

typedef struct S {
    int i;
    char c;
} S;

_Alignof(S) // 4;

新增關鍵字 _Alignas 以聲明對齊毡泻,其形式為 _Alignas(整型常量表達式或類型),對齊為整型常量表達式的值或類型的 _Alignof 的值芯咧,如:

typedef struct S {
    _Alignas(16) char s[42];
};

2.1.2. 預處理

2.1.2.1. 宏

__STDC_VERSION__ 的值為 201112L牙捉。

新增宏 __STDC_UTF_16__竹揍,當 char16_t 使用 UTF-16 編碼則為 1

新增宏 __STDC_UTF_32__邪铲,當 char32_t 使用 UTF-32 編碼則為 1芬位。

新增宏 __STDC_ANALYZABLE__,當編譯器支持可分析性則為 1带到。

新增宏 __STDC_LIB_EXT1__昧碉,當標準庫包含帶邊界檢查的特定 API 則為 201112L

新增宏 __STDC_NO_ATOMICS__揽惹,當編譯器不支持原子類型且標準庫不包含原子類型 API 則為 1被饿。

新增宏 __STDC_NO_COMPLEX__,當編譯器不支持復數(shù)類型且標準庫不包含復數(shù)類型 API 則為 1搪搏。

新增宏 __STDC_NO_VLA__狭握,當編譯器不支持變長數(shù)組則為 1

2.1.3. 表達式

2.1.3.1. 字面量

新增字符字面量前綴 u疯溺,字符類型為 char16_t论颅,通常是 UTF-16 編碼。如 u'我'(char16_t)0x6211囱嫩,若字符的 Unicode 碼點對應的 UTF-16 編碼超出單個編碼單元恃疯,則依照編譯器的具體實現(xiàn)。

新增字符字面量前綴 U墨闲,字符類型為 char32_t今妄,通常是 UTF-32 編碼。如 U'我'(char32_t)0x00006211鸳碧,若字符的 Unicode 碼點對應的 UTF-32 編碼超出單個編碼單元(這都能超過盾鳞?),則依照編譯器的具體實現(xiàn)杆兵。

新增字符串字面量前綴 u8雁仲,字符類型為 char仔夺,UTF-8 編碼琐脏。如 u"是我"(char[]){ 0xe6, 0x98, 0xaf, 0xe6, 0x88, 0x91, 0 }

新增字符串字面量前綴 u缸兔,字符類型為 char16_t日裙,通常是 UTF-16 編碼。如 u"是我"(char16_t[]){ 0x662f, 0x6211, 0 }惰蜜。

新增字符串字面量前綴 U昂拂,字符類型為 char32_t,通常是 UTF-32 編碼抛猖。如 U"是我"(char32_t[]){ 0x0000662f, 0x00006211, 0 }格侯。

2.1.3.2. 泛型選擇表達式

新增關鍵字 _Generic 以提供泛型選擇表達式鼻听,其形式為 _Generic(控制表達式, 關聯(lián)列表)。關聯(lián)列表中的關聯(lián)項由逗號分隔联四,關聯(lián)項的形式為 類型名: 表達式default: 表達式撑碴,各表達式不能為逗號表達式〕眨控制表達式會經(jīng)歷左值轉(zhuǎn)換(去掉頂層的類型限定符醉拓、數(shù)組到指針、函數(shù)到指針)但不會求值收苏,轉(zhuǎn)換后的類型與各關聯(lián)項中的類型名進行匹配亿卤,返回匹配到的關聯(lián)項中的表達式,若無 default 項且無匹配項則編譯出錯鹿霸。如:

int i = 42;
j = _Generic(i,
    char: i + 1,
    int: i + 2,
    default: i + 3
); // 44

2.1.3.3. 靜態(tài)斷言

新增關鍵字 _Static_assert 以提供靜態(tài)斷言排吴,其形式為 _Static_assert(整型常量表達式, 字符串字面量),靜態(tài)斷言在編譯時進行懦鼠,當整型常量表達式的值為 0 則發(fā)生編譯錯誤傍念,字符串字面量會出現(xiàn)在錯誤信息中。

2.1.4. 聲明

2.1.4.1. 存儲期說明符

新增關鍵字 _Thread_local 以聲明變量的存儲期為新增的線程存儲期葛闷。線程存儲期為該線程的整個執(zhí)行過程憋槐,變量在線程啟動時初始化。不能用于函數(shù)聲明淑趾。用于在塊作用域中聲明時阳仔,必須與 staticextern 存儲期組合。

2.1.4.2. 原子類型

新增關鍵字 _Atomic 以聲明變量為原子類型扣泊。

不能用于數(shù)組和函數(shù)聲明近范,如:

typedef int pair[2];
// _Atomic pair p;

但可聲明元素為原子類型的數(shù)組,如:

_Atomic int p[2];

2.1.5. 類型

2.1.5.1. 標量

新增 16 位和 32 位無符號字符類型 char16_tchar32_t延蟹,通常是 typedef评矩。

2.2. 標準庫級

2.2.1. 線程

新增線程支持庫

頭文件 <threads.h>

新增線程、線程局部存儲和同步原語操作函數(shù)阱飘。

頭文件 <stdatomic.h>

新增原子操作函數(shù)斥杜。

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沥匈,隨后出現(xiàn)的幾起案子蔗喂,更是在濱河造成了極大的恐慌,老刑警劉巖高帖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缰儿,死亡現(xiàn)場離奇詭異,居然都是意外死亡散址,警方通過查閱死者的電腦和手機乖阵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門宣赔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瞪浸,你說我怎么就攤上這事拉背。” “怎么了默终?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵椅棺,是天一觀的道長。 經(jīng)常有香客問我齐蔽,道長两疚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任含滴,我火速辦了婚禮诱渤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谈况。我一直安慰自己勺美,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布碑韵。 她就那樣靜靜地躺著赡茸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祝闻。 梳的紋絲不亂的頭發(fā)上占卧,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音联喘,去河邊找鬼华蜒。 笑死,一個胖子當著我的面吹牛豁遭,可吹牛的內(nèi)容都是我干的叭喜。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼蓖谢,長吁一口氣:“原來是場噩夢啊……” “哼捂蕴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜈抓,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤启绰,失蹤者是張志新(化名)和其女友劉穎昂儒,沒想到半個月后沟使,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡渊跋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年腊嗡,在試婚紗的時候發(fā)現(xiàn)自己被綠了着倾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡燕少,死狀恐怖卡者,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情客们,我是刑警寧澤崇决,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站底挫,受9級特大地震影響恒傻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜建邓,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一盈厘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧官边,春花似錦沸手、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至诡渴,卻和暖如春栅隐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玩徊。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工租悄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恩袱。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓泣棋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親畔塔。 傳聞我的和親對象是個殘疾皇子潭辈,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容