30分钟了解C 11新特性
什么是C 11
C 11是曾經(jīng)被叫做C 0x,是對目前C 語言的擴展和修正,C 11不僅包含核心語言的新機能,而且擴展了C 的標準程序庫(STL),并入了大部分的C Technical Report 1(TR1)程序庫(數(shù)學的特殊函數(shù)除外)。
C 11包括大量的新特性:包括lambda表達式,類型推導關鍵字auto、decltype,和模板的大量改進。
本文將對C 11的以上新特性進行簡單的講解,以便大家能夠快速了解到C 11對C 的易用性方面祈禱的巨大作用。
新的關鍵字
auto
C 11中引入auto***種作用是為了自動類型推導
auto的自動類型推導,用于從初始化表達式中推斷出變量的數(shù)據(jù)類型。通過auto的自動類型推導,可以大大簡化我們的編程工作
auto實際上實在編譯時對變量進行了類型推導,所以不會對程序的運行效率造成不良影響
另外,似乎auto并不會影響編譯速度,因為編譯時本來也要右側(cè)推導然后判斷與左側(cè)是否匹配。
auto?a;?//?錯誤,auto是通過初始化表達式進行類型推導,如果沒有初始化表達式,就無法確定a的類型??auto?i?=?1;??auto?d?=?1.0;??auto?str?=?"Hello?World";??auto?ch?=?'A';??auto?func?=?less();??vector?iv;??auto?ite?=?iv.begin();??auto?p?=?new?foo()?//?對自定義類型進行類型推導auto不光有以上的應用,它在模板中也是大顯身手,比如下例這個加工產(chǎn)品的例子中,如果不使用auto就必須聲明Product這一模板參數(shù):
template???void?processProduct(const?Creator&?creator)?{??????Product*?val?=?creator.makeobject();??????//?do?somthing?with?val??}?????????????????.如果使用auto,則可以這樣寫:
template???void?processProduct(const?Creator&?creator)?{??????auto?val?=?creator.makeobject();??????//?do?somthing?with?val??}拋棄了麻煩的模板參數(shù),整個代碼變得更加正解了。
decltype
decltype實際上有點像auto的反函數(shù),auto可以讓你聲明一個變量,而decltype則可以從一個變量或表達式中得到類型,有實例如下:
int?x?=?3;??decltype(x)?y?=?x;有人會問,decltype的實用之處在哪里呢,我們接著上邊的例子繼續(xù)說下去,如果上文中的加工產(chǎn)品的例子中我們想把產(chǎn)品作為返回值該怎么辦呢?我們可以這樣寫:
template???auto?processProduct(const?Creator&?creator)?->?decltype(creator.makeobject())?{??????auto?val?=?creator.makeobject();??????//?do?somthing?with?val??}nullptr
nullptr是為了解決原來C 中NULL的二義性問題而引進的一種新的類型,因為NULL實際上代表的是0,
void?F(int?a){??????cout<<a<<endl;??}???void?F(int?*p){??????assert(p?!=?NULL);???????cout<<?p?<<endl;??}???int?main(){???????int?*p?=?nullptr;??????int?*q?=?NULL;??????bool?equal?=?(?p?==?q?);?//?equal的值為true,說明p和q都是空指針??????int?a?=?nullptr;?//?編譯失敗,nullptr不能轉(zhuǎn)型為int??????F(0);?//?在C 98中編譯失敗,有二義性;在C 11中調(diào)用F(int)??????F(nullptr);???????return?0;??}序列for循環(huán)
在C 中for循環(huán)可以使用類似java的簡化的for循環(huán),可以用于遍歷數(shù)組,容器,string以及由begin和end函數(shù)定義的序列(即有Iterator),示例代碼如下:
map?m{{"a",?1},?{"b",?2},?{"c",?3}};??for?(auto?p?:?m){??????cout<<p.first<<"?:?"<<p.second<<endl;??}Lambda表達式
lambda表達式類似javascript中的閉包,它可以用于創(chuàng)建并定義匿名的函數(shù)對象,以簡化編程工作。Lambda的語法如下:
[函數(shù)對象參數(shù)](操作符重載函數(shù)參數(shù))->返回值類型{函數(shù)體}
vector?iv{5,?4,?3,?2,?1};??int?a?=?2,?b?=?1;???for_each(iv.begin(),?iv.end(),?[b](int?&x){cout<<(x? ?b)<int{return?x?*?(a? ?b);});//?(3)[]內(nèi)的參數(shù)指的是Lambda表達式可以取得的全局變量。(1)函數(shù)中的b就是指函數(shù)可以得到在Lambda表達式外的全局變量,如果在[]中傳入=的話,即是可以取得所有的外部變量,如(2)和(3)Lambda表達式
()內(nèi)的參數(shù)是每次調(diào)用函數(shù)時傳入的參數(shù)。
->后加上的是Lambda表達式返回值的類型,如(3)中返回了一個int類型的變量
變長參數(shù)的模板
我們在C 中都用過pair,pair可以使用make_pair構(gòu)造,構(gòu)造一個包含兩種不同類型的數(shù)據(jù)的容器。比如,如下代碼:
auto?p?=?make_pair(1,?"C ?11");由于在C 11中引入了變長參數(shù)模板,所以發(fā)明了新的數(shù)據(jù)類型:tuple,tuple是一個N元組,可以傳入1個, 2個甚至多個不同類型的數(shù)據(jù)
auto?t1?=?make_tuple(1,?2.0,?"C ?11");??auto?t2?=?make_tuple(1,?2.0,?"C ?11",?{1,?0,?2});這樣就避免了從前的pair中嵌套pair的丑陋做法,使得代碼更加整潔
另一個經(jīng)常見到的例子是Print函數(shù),在C語言中printf可以傳入多個參數(shù),在C 11中,我們可以用變長參數(shù)模板實現(xiàn)更簡潔的Print
template??void?Print(Head?head,?typename...?tail)?{??????cout<<?head?<<endl;??????Print(tail...);??}Print中可以傳入多個不同種類的參數(shù),如下:
Print(1,?1.0,?"C 11");更加優(yōu)雅的初始化方法
在引入C 11之前,只有數(shù)組能使用初始化列表,其他容器想要使用初始化列表,只能用以下方法:
int?arr[3]?=?{1,?2,?3}??vector?v(arr,?arr? ?3);在C 11中,我們可以使用以下語法來進行替換:
int?arr[3]{1,?2,?3};??vector?iv{1,?2,?3};??map{{1,?"a"},?{2,?"b"}};??string?str{"Hello?World"};來源:http://my.oschina.net/wangxuanyihaha/blog/183151
總結(jié)
以上是生活随笔為你收集整理的30分钟了解C 11新特性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Linux C语言编程基本原理与实践
 - 下一篇: iPhone8Plus重量有多少克