第六章 摘錄

6.1 函數(shù)基礎(chǔ)

一個(gè)典型的函數(shù)定義包括如下部分:返回類型、函數(shù)名、參數(shù)列表以及函數(shù)體盛杰。

通過(guò)調(diào)用運(yùn)算符(call operator)來(lái)執(zhí)行函數(shù)。調(diào)用運(yùn)算符的形式是一對(duì)圓括號(hào)藐石,它作用于一個(gè)表達(dá)式即供,該表達(dá)式是函數(shù)或者指向函數(shù)的指針。

函數(shù)的調(diào)用完成兩項(xiàng)工作:1.用實(shí)參初始化函數(shù)對(duì)應(yīng)的形參 2.將控制權(quán)轉(zhuǎn)移給被調(diào)用函數(shù)于微,此時(shí)主調(diào)函數(shù)的執(zhí)行被暫時(shí)中斷逗嫡,被調(diào)函數(shù)開始執(zhí)行。

當(dāng)遇到一條return語(yǔ)句時(shí)函數(shù)結(jié)束執(zhí)行的過(guò)程角雷。和函數(shù)調(diào)用一樣祸穷,return語(yǔ)句也完成兩項(xiàng)工作:1.返回return語(yǔ)句中的值(如果有的話)2.將控制權(quán)從被調(diào)函數(shù)轉(zhuǎn)移回主調(diào)函數(shù)。

函數(shù)的返回類型不能是數(shù)組類型或者函數(shù)類型勺三,但可以是指向數(shù)組或者函數(shù)的指針雷滚。

在所有函數(shù)體之外定義的對(duì)象存在于程序的整個(gè)執(zhí)行過(guò)程中。此類對(duì)象在程序啟動(dòng)時(shí)被創(chuàng)建吗坚,直到程序結(jié)束才銷毀祈远。

自動(dòng)對(duì)象:對(duì)于普通局部變量對(duì)應(yīng)的對(duì)象來(lái)說(shuō)呆万,當(dāng)函數(shù)的控制路徑經(jīng)過(guò)變量定義語(yǔ)句時(shí)創(chuàng)建該對(duì)象,當(dāng)?shù)竭_(dá)定義所在的塊末尾時(shí)銷毀它车份。把只存在于塊執(zhí)行期間的對(duì)象稱為自動(dòng)對(duì)象(automatic object)谋减。當(dāng)塊的執(zhí)行結(jié)束后,塊中創(chuàng)建的自動(dòng)對(duì)象的值就變成未定義的了扫沼。

局部靜態(tài)對(duì)象:某些時(shí)候出爹,有必要令局部變量的生命周期貫穿函數(shù)調(diào)用及之后的時(shí)間,此時(shí)可以將局部變量定義成static類型缎除。

類似于變量严就,函數(shù)只能定義一次,但可以聲明多次器罐。函數(shù)聲明無(wú)須函數(shù)體梢为,用一個(gè)分號(hào)替代即可。因?yàn)楹瘮?shù)的聲明不包含函數(shù)體轰坊,所以也就無(wú)須形參的名字铸董。事實(shí)上,在函數(shù)的聲明中經(jīng)常省略形參的名字肴沫。盡管如此粟害,寫上形參的名字還是有用處的,可以幫助使用者更好理解函數(shù)的功能樊零。函數(shù)聲明也被稱作函數(shù)原型(function prototype)我磁。

之前曾建議過(guò)變量在頭文件中聲明,在源文件中定義驻襟。函數(shù)也應(yīng)如此夺艰。

分離式編譯:允許我們把程序分割到幾個(gè)文件中去,每個(gè)文件獨(dú)立編譯沉衣。

6.2 參數(shù)傳遞

如果形參是引用類型郁副,它將綁定到對(duì)應(yīng)的實(shí)參上;否則豌习,將實(shí)參的值拷貝后賦給形參存谎。

當(dāng)形參是引用類型時(shí),我們說(shuō)它對(duì)應(yīng)的實(shí)參被引用傳遞肥隆。如果是拷貝既荚,則說(shuō)這樣的實(shí)參被值傳遞

使用引用避免拷貝:拷貝大的類類型對(duì)象或者容器對(duì)象比較低效栋艳,甚至有的類型根本就不支持拷貝操作恰聘。如比較兩個(gè)string對(duì)象長(zhǎng)度的函數(shù),形參就可以為const string &s1...這既避免了引用操作,又能保證string對(duì)象不被修改晴叨。

使用引用參數(shù)可以返回額外的信息凿宾,如一個(gè)函數(shù)想返回多個(gè)參數(shù),那么可以選擇return一種新的數(shù)據(jù)類型兼蕊,讓它包含多個(gè)信息成員初厚。另一種更簡(jiǎn)單的辦法就是給函數(shù)傳入一個(gè)額外的引用實(shí)參,讓其來(lái)保存信息孙技。

數(shù)組的兩個(gè)特殊性質(zhì):不允許拷貝數(shù)組产禾,使用數(shù)組時(shí)(通常)會(huì)將其轉(zhuǎn)換成指針。因此绪杏,我們無(wú)法以值傳遞方式使用數(shù)組參數(shù)下愈,所以當(dāng)為函數(shù)傳遞一個(gè)數(shù)組時(shí)纽绍,實(shí)際上傳遞的時(shí)指向數(shù)組首元素的指針蕾久。

void print(const int*);? ?

void print(const int[]);?

void print(const int[10]);//這里的維度表示我們期望數(shù)組含有多少元素,實(shí)際不一定

盡管形式不同拌夏,這三個(gè)函數(shù)是等價(jià)的僧著。每個(gè)函數(shù)的唯一形參都是const int*類型的。

int (*matrix)[10]; //指向含有10個(gè)整數(shù)的數(shù)組的指針

void print(int matrix[][10], int rowSize) { /*...*/ }? ?//等價(jià)定義

下面print函數(shù)中matrix的聲明看起來(lái)是一個(gè)二維數(shù)組障簿,實(shí)際上形參是指向含有10個(gè)整數(shù)的數(shù)組的指針盹愚。因?yàn)榫幾g器會(huì)一如既往地忽略掉第一個(gè)維度,所以最好不要把它包括在形參列表內(nèi)站故。

為了編寫能處理不同數(shù)量實(shí)參的函數(shù)皆怕。c++11提供了兩種主要方法:1.如果所有實(shí)參類型相同,可以傳遞名為initializer_list的標(biāo)準(zhǔn)庫(kù)類型西篓;如果實(shí)參的類型不同愈腾,則編寫一種特殊的函數(shù),也就是所謂的可變參數(shù)模板岂津。

6.3 返回類型和return語(yǔ)句

void類型函數(shù)隱式地執(zhí)行了return虱黄。void類型函數(shù)也能使用return expression;,不過(guò)此時(shí)的expression必須是另一個(gè)返回void的函數(shù)吮成,否則會(huì)產(chǎn)生編譯錯(cuò)誤橱乱。

調(diào)用一個(gè)返回引用的函數(shù)得到左值,其他返回類型得到右值粱甫。

c++11新標(biāo)準(zhǔn)規(guī)定泳叠,函數(shù)可以返回花括號(hào)包圍的值的列表。如vector<string> function(),返回值可以是{},{"xxx","yyy"}茶宵。若函數(shù)返回的是內(nèi)置類型危纫,則花括號(hào)包圍的列表最多包含一個(gè)值,而且該值所占空間不應(yīng)該大于目標(biāo)類型的空間。若返回的是類類型叶摄,由類本身定義初始值如何使用属韧。

如果想定義一個(gè)返回?cái)?shù)組指針的函數(shù),則數(shù)組維度必須跟在函數(shù)名字之后蛤吓。函數(shù)的形參列表也跟在函數(shù)名字后面且形參列表應(yīng)該先于數(shù)組的維度宵喂。如:int (*func(int i))[10];? 要從里到外逐層理解其含義。

在C++11新標(biāo)準(zhǔn)中会傲,還有一種簡(jiǎn)化上述func聲明的方法锅棕,就是用尾置返回類型。如:auto func(int i) -> int(*)[10];

P206的三個(gè)練習(xí)

6.4 函數(shù)重載

如果同一作用域內(nèi)的幾個(gè)函數(shù)名字相同但形參列表不同淌山,稱之為重載函數(shù)裸燎。

重載主要是由編譯器根據(jù)傳遞的實(shí)參類型推斷想要的是哪個(gè)函數(shù)。

main函數(shù)不能重載泼疑。

一個(gè)擁有頂層const的形參無(wú)法和另一個(gè)沒有頂層const的形參區(qū)分開來(lái)德绿。

如果形參是某種類型的指針或引用,則通過(guò)區(qū)分其指向的是常量對(duì)象還是非常量對(duì)象可以實(shí)現(xiàn)函數(shù)重載退渗,此時(shí)的const是底層的移稳。

建議:最好只重載那些確實(shí)非常相似的操作。有些情況下会油,給函數(shù)起不同的名字能使得程序更易理解个粱。

函數(shù)匹配是指一個(gè)過(guò)程,在這個(gè)過(guò)程中把函數(shù)調(diào)用與一組重載函數(shù)中的某一個(gè)關(guān)聯(lián)起來(lái)翻翩,函數(shù)匹配也叫做重載確定都许。

如果在內(nèi)層作用域中聲明名字,它將隱藏外層作用域中聲明的同名實(shí)體嫂冻。在不同的作用域中無(wú)法重載函數(shù)名胶征。一旦在當(dāng)前作用域中找到了所需的名字,編譯器就會(huì)忽略掉外層作用域中的同名實(shí)體絮吵。

在C++中弧烤,名字查找發(fā)生在類型檢查之前。

6.5 特殊用途語(yǔ)言特性

6.5.1 默認(rèn)實(shí)參

一旦某個(gè)形參被賦予了默認(rèn)值蹬敲,它后面的所有形參都必須有默認(rèn)值暇昂。

函數(shù)聲明通常放在頭文件中,并且一個(gè)函數(shù)只聲明一次伴嗡,但是多次聲明同一個(gè)函數(shù)也是合法的急波。但要注意在給定的作用域中一個(gè)形參只能被賦予一次默認(rèn)實(shí)參。換句話說(shuō)瘪校,函數(shù)后續(xù)聲明只能為之前那些沒有默認(rèn)值的形參添加默認(rèn)實(shí)參澄暮,而且該形參右側(cè)的所有形參必須都有默認(rèn)值名段。

6.5.2 內(nèi)聯(lián)函數(shù)和constexpr函數(shù)

在大多數(shù)機(jī)器上,一次函數(shù)調(diào)用包含著一系列工作:調(diào)用前要先保存寄存器泣懊,并在返回時(shí)恢復(fù)伸辟;可能需要拷貝實(shí)參;程序轉(zhuǎn)向一個(gè)新的位置繼續(xù)執(zhí)行馍刮。

將函數(shù)指定為內(nèi)斂函數(shù)信夫,通常就是將它在每個(gè)調(diào)用點(diǎn)上“內(nèi)聯(lián)地”展開。

一般來(lái)說(shuō)卡啰,內(nèi)聯(lián)機(jī)制用于優(yōu)化規(guī)模較小静稻、流程直接、頻繁調(diào)用的函數(shù)匈辱。

constexpr函數(shù)是指能用于常量表達(dá)式的函數(shù)振湾。有如下約定:函數(shù)的返回類型及所有形參的類型都得是字面值類型,而且函數(shù)體必須有且只有一條return語(yǔ)句亡脸。

6.5.3 調(diào)試幫助

assert是一種預(yù)處理宏押搪。所謂預(yù)處理宏其實(shí)是一個(gè)預(yù)處理變量,它的行為有點(diǎn)類似于內(nèi)聯(lián)函數(shù)梗掰。 預(yù)處理名字由預(yù)處理器而非編譯器管理嵌言,所以可以直接使用該名字而無(wú)須提供using聲明。

assert(expr);? 首先對(duì)expr求值及穗,如果表達(dá)式為假(即0),assert輸出信息并終止程序的執(zhí)行绵载。如果表達(dá)式為真(即非0)埂陆,assert什么也不做。常用于檢查“不能發(fā)生”的條件娃豹。

assert宏定義在cassert頭文件中焚虱。宏名字在程序內(nèi)必須唯一。

NDEBUG預(yù)處理變量懂版,如果定義了NDEBUG鹃栽,則assert什么也不做∏耄可以使用一個(gè)#define語(yǔ)句定義NDEBUG民鼓,從而關(guān)閉調(diào)試狀態(tài)。定義NDEBUG能避免檢查各種條件所需的運(yùn)行時(shí)開銷蓬抄。

可把a(bǔ)ssert當(dāng)成調(diào)試程序的一種輔助手段丰嘉,但是不能用它替代真正的運(yùn)行時(shí)邏輯檢查,也不能替代程序本身應(yīng)該包含的錯(cuò)誤檢查嚷缭。

C++編譯器定義了幾個(gè)對(duì)于程序調(diào)試很有用的名字:__func__饮亏、__FILE__耍贾、__LINE__、__TIME__路幸、__DATE__荐开。

6.6 函數(shù)匹配

先選出候選函數(shù)(所有同名重載函數(shù),且其聲明在調(diào)用點(diǎn)可見)->再選出可行函數(shù)(實(shí)參類型是否與形參匹配)->尋找最佳匹配(如果有的話)简肴。

含有多個(gè)形參的函數(shù)匹配誓焦,如果在尋找最佳匹配時(shí)出現(xiàn)二義性,編譯器就會(huì)拒絕這個(gè)調(diào)用請(qǐng)求着帽。

6.7 函數(shù)指針

函數(shù)指針指向的時(shí)函數(shù)而非對(duì)象杂伟。

當(dāng)我們把函數(shù)名作為一個(gè)值使用時(shí),該函數(shù)自動(dòng)地轉(zhuǎn)換成指針(類似數(shù)組)仍翰。如func是函數(shù)名,pf = func;與pf = &func;是等價(jià)的赫粥。

此外,還能直接使用指向函數(shù)的指針調(diào)用該函數(shù)予借,無(wú)須提前解引用指針越平。

雖然不能定義函數(shù)類型的形參,但是形參可以是指向函數(shù)的指針灵迫。


秦叛。。瀑粥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挣跋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子狞换,更是在濱河造成了極大的恐慌避咆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件修噪,死亡現(xiàn)場(chǎng)離奇詭異查库,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)黄琼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門樊销,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人脏款,你說(shuō)我怎么就攤上這事围苫。” “怎么了弛矛?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵够吩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我丈氓,道長(zhǎng)周循,這世上最難降的妖魔是什么强法? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮湾笛,結(jié)果婚禮上饮怯,老公的妹妹穿的比我還像新娘。我一直安慰自己嚎研,他們只是感情好蓖墅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著临扮,像睡著了一般论矾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杆勇,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天贪壳,我揣著相機(jī)與錄音,去河邊找鬼蚜退。 笑死闰靴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钻注。 我是一名探鬼主播蚂且,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼幅恋!你這毒婦竟也來(lái)了杏死?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤佳遣,失蹤者是張志新(化名)和其女友劉穎识埋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體零渐,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年系忙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诵盼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡银还,死狀恐怖风宁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛹疯,我是刑警寧澤戒财,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站捺弦,受9級(jí)特大地震影響饮寞,放射性物質(zhì)發(fā)生泄漏孝扛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一幽崩、第九天 我趴在偏房一處隱蔽的房頂上張望苦始。 院中可真熱鬧,春花似錦慌申、人聲如沸陌选。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)咨油。三九已至,卻和暖如春柒爵,著一層夾襖步出監(jiān)牢的瞬間役电,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工餐弱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宴霸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓膏蚓,卻偏偏與公主長(zhǎng)得像瓢谢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子驮瞧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,511評(píng)論 1 51
  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,764評(píng)論 0 38
  • 題目類型 a.C++與C差異(1-18) 1.C和C++中struct有什么區(qū)別氓扛? C沒有Protection行為...
    阿面a閱讀 7,643評(píng)論 0 10
  • 與自己的身體做朋友,你的精力才會(huì)越來(lái)越充沛论笔。 什么叫做朋友采郎?不委屈他但也絕不會(huì)慣著他,他才會(huì)跟你一起成長(zhǎng)狂魔,一起變得更好蒜埋。
    河洛一劍閱讀 291評(píng)論 0 0
  • 過(guò)了三十會(huì)發(fā)現(xiàn)朋友越來(lái)越少,有的好朋友會(huì)越來(lái)越好最楷,也有的卻會(huì)分道揚(yáng)鑣整份。 朋友之間的感情很微妙,需要呵護(hù)籽孙,一不小心友...
    行走傳說(shuō)閱讀 144評(píng)論 0 1