文章目錄
- 第6章 函數(shù)
- 6.1 函數(shù)基礎(chǔ)
- 6.1.1 局部對(duì)象
- 6.1.2 函數(shù)聲明
- 6.1.3 分離式編譯
- 6.2 參數(shù)傳遞
- 6.2.1 傳值參數(shù)
- 6.2.2 傳引用參數(shù)
- 6.2.3 const形參和實(shí)參
- 6.2.4 數(shù)組形參
- 6.2.5 main處理命令行選項(xiàng)
- 6.2.6 含可變形參的函數(shù)
- 6.3 返回類型和return語(yǔ)句
- 6.3.1 無(wú)返回值函數(shù)
- 6.3.2 有返回值函數(shù)
- 6.3.3 返回?cái)?shù)組指針
- 6.4 函數(shù)重載
- 6.4.1 重載與作用域
- 6.5 特殊用途語(yǔ)言特性
- 6.5.1 默認(rèn)實(shí)參
- 6.5.2 內(nèi)聯(lián)函數(shù)和constexpr函數(shù)
- 6.5.3 調(diào)試幫助
- 6.6 函數(shù)匹配
- 6.7 函數(shù)指針
- 小結(jié)
- 術(shù)語(yǔ)表
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:
主機(jī)域名、虛擬空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、
秦州網(wǎng)站維護(hù)、網(wǎng)站推廣。第6章 函數(shù)
- 函數(shù)定義和聲明(函數(shù)傳參/返回值/重載(調(diào)用匹配)/函數(shù)指針)
- 函數(shù) 命名了的代碼塊 可以有0/多個(gè)參數(shù) 通常產(chǎn)生一個(gè)結(jié)果 可以重載
6.1 函數(shù)基礎(chǔ)
- 函數(shù)定義:返回類型、函數(shù)名字和0個(gè)或者多個(gè)形參組成的列表以及函數(shù)體
- 調(diào)用運(yùn)算符:調(diào)用運(yùn)算符的形式是一對(duì)圓括號(hào),它作用于一個(gè)表達(dá)式,該表達(dá)式是函數(shù)或者指向函數(shù)的指針,圓括號(hào)之內(nèi)是用逗號(hào)隔開的實(shí)參列表,用實(shí)參初始化函數(shù)的形參
- 編寫函數(shù)
- 調(diào)用函數(shù)
- 用實(shí)參初始化函數(shù)對(duì)應(yīng)的形參
- 將控制權(quán)轉(zhuǎn)移給被調(diào)用函數(shù)
- 主調(diào)函數(shù)執(zhí)行被中斷,被調(diào)函數(shù)開始執(zhí)行
- return語(yǔ)句:
- 返回return語(yǔ)句中的值
- 將控制權(quán)從被調(diào)函數(shù)轉(zhuǎn)移回主調(diào)函數(shù)
- 形參和實(shí)參
- 實(shí)參是形參的初始值(沒有規(guī)定實(shí)參的求值順序)
- 實(shí)參的類型必須與對(duì)應(yīng)的形參類型匹配(實(shí)參數(shù)目)
- 函數(shù)的形參列表
- 可以為空 但不能省略
- 形參列表中的形參用逗號(hào)隔開 每個(gè)形參都是含有一個(gè)聲明符的聲明
- 任意形參不能同名,函數(shù)最外層作用域局部變量也不能與形參同名
- 形參名可選 但必須為它提供一個(gè)實(shí)參
- 函數(shù)返回類型
- 返回類型不能是數(shù)組類型或者函數(shù)類型,但可以是指向數(shù)組或者函數(shù)的指針
6.1.1 局部對(duì)象
- 名字作用域:程序文本一部分,名字在其中可見
- 對(duì)象生命周期:程序執(zhí)行過(guò)程中對(duì)象存在的一段時(shí)間
- 局部變量:形參和函數(shù)體內(nèi)部定義的變量(會(huì)隱藏在外層作用域中同名的其他所有聲明)
- 自動(dòng)對(duì)象
- 局部靜態(tài)對(duì)象
- static類型:令局部變量的生命周期貫穿函數(shù)調(diào)用及之后的時(shí)間
- 若沒有顯式初始值將執(zhí)行值初始化 內(nèi)置類型局部靜態(tài)變量初始化為0
6.1.2 函數(shù)聲明
- 函數(shù)聲明(也稱函數(shù)原型)無(wú)需函數(shù)體(無(wú)須形參名字)
- 函數(shù)三要素:返回類型/函數(shù)名/形參類型
- 在頭文件中進(jìn)行函數(shù)聲明
- 頭文件聲明,源文件定義,源文件包含頭文件,編譯器驗(yàn)證函數(shù)定義與聲明是否匹配
6.1.3 分離式編譯
- 編寫程序時(shí)按照邏輯關(guān)系將其劃分開來(lái),每個(gè)文件獨(dú)立編譯
- 編譯和鏈接多個(gè)源文件
- $:系統(tǒng)提示符;CC:編譯器名字;#:命令行下的注釋語(yǔ)句
- 若修改了其中一個(gè)源文件,只需重新編譯改動(dòng)了的文件,產(chǎn)生.o/.obj文件(該文件包含對(duì)象代碼)
- 編譯器負(fù)責(zé)把對(duì)象文件鏈接在一起形成可執(zhí)行文件
6.2 參數(shù)傳遞
- 每次調(diào)用函數(shù)都會(huì)重新創(chuàng)建它的形參 用傳入的實(shí)參對(duì)形參進(jìn)行初始化(初始化機(jī)理與變量初始化一樣)
- 引用/傳引用傳遞:形參為引用類型,將綁定到對(duì)應(yīng)的實(shí)參上(引用形參是對(duì)應(yīng)實(shí)參別名)
- 值/傳值傳遞:形參和實(shí)參是兩個(gè)相互獨(dú)立的對(duì)象,實(shí)參的值被拷貝給形參
6.2.1 傳值參數(shù)
- 初始化非引用類型變量 初始值被拷貝給變量,對(duì)變量的改動(dòng)不會(huì)影響初始值
- 指針形參
- 指針行為與其他非引用類型一樣:執(zhí)行指針拷貝時(shí),拷貝的是指針的值,拷貝后兩個(gè)指針是不同的指針(但他們指向的地址是相同的)
- c程序員常使用指針類型形參訪問函數(shù)外部對(duì)象,c++建議使用引用類型形參代替指針
6.2.2 傳引用參數(shù)
- 對(duì)引用的操作實(shí)際上是作用在引用所引的對(duì)象上
- 使用引用避免拷貝
- 當(dāng)某種類型不支持拷貝操作時(shí),只能使用引用形參訪問該類型對(duì)象
- 如無(wú)需改變形參對(duì)象的內(nèi)容,可將其定義為對(duì)常量的引用(當(dāng)函數(shù)無(wú)需修改引用形參的值時(shí)最好將其聲明為常量引用)
- 使用引用形參返回額外信息
- 返回多個(gè)結(jié)果可以定義一個(gè)新的數(shù)據(jù)類型,讓它包含多個(gè)成員
- 給函數(shù)傳入額外的引用實(shí)參
6.2.3 const形參和實(shí)參
- 與其他初始化一樣,用實(shí)參初始化形參時(shí)會(huì)忽略掉頂層const,當(dāng)形參有頂層const時(shí),可以傳給它常量或者非常量對(duì)象。(因?yàn)轫攲觕onst被忽略所以在函數(shù)重載時(shí),有無(wú)頂層const的形參是一樣的,不能進(jìn)行這樣的重載)
- 指針或引用形參與const
- 形參的初始化方式和變量的初始化方式是一樣的
- tip:
- 不能用字面值初始化一個(gè)非常量引用(但可以初始化常量引用)
- 不能把普通引用綁定到const對(duì)象上
- 不能把普通引用綁定到字面值上
- 盡量使用常量引用
- 使用引用而非常量引用會(huì)極大限制函數(shù)所能接受的實(shí)參類型
- 例如不能把const對(duì)象/字面值/需要類型轉(zhuǎn)換的對(duì)象傳遞給普通引用對(duì)象
6.2.4 數(shù)組形參
- 數(shù)組特殊性質(zhì)
- 不允許拷貝數(shù)組
- 使用數(shù)組時(shí)通常會(huì)將其轉(zhuǎn)換為指針(指向數(shù)組首元素的指針)
- 但是可以將形參寫成類似數(shù)組的形式,如
(const int[])/(const int[10])
但最終唯一形參都是(const int*)
- 數(shù)組的大小對(duì)函數(shù)調(diào)用沒有影響(但須確保使用數(shù)組時(shí)不會(huì)越界)。因數(shù)組以指針形式傳遞給數(shù)組,函數(shù)不知道數(shù)組數(shù)組尺寸,調(diào)用者須為此提供些額外信息
- 管理指針形參的三種常用技術(shù)
- 使用標(biāo)記指定數(shù)組長(zhǎng)度
- 適用于有明顯結(jié)束標(biāo)記且該標(biāo)記不會(huì)與普通數(shù)據(jù)混淆的情況,如C風(fēng)格字符串末尾空字符
- 使用標(biāo)準(zhǔn)庫(kù)規(guī)范
- 傳遞指向數(shù)組首元素和尾后元素的指針(begin end)
- 顯示傳遞一個(gè)表示數(shù)組大小的形參
- 通過(guò)形參確定數(shù)組元素個(gè)數(shù),如個(gè)數(shù)可為
end(j)-begin(j)
- 數(shù)組形參和const
- 當(dāng)函數(shù)不需要對(duì)數(shù)組元素執(zhí)行寫操作的時(shí)候,數(shù)組形參應(yīng)該是指向const的指針
- 只有當(dāng)函數(shù)確實(shí)需要改變?cè)刂档臅r(shí)候才把形參定義成指向非常量的指針
- 數(shù)組引用形參
- c++允許將變量定義成數(shù)組的引用,形參也可以是數(shù)組的引用(數(shù)組名
(int (&arr)[10])
兩端的括號(hào)必不可少) - 數(shù)組的大小是構(gòu)成數(shù)組類型的一部分,只要不超過(guò)維度在函數(shù)體內(nèi)就可以放心的使用數(shù)組
- 傳遞多維數(shù)組
- 多維數(shù)組其實(shí)是數(shù)組的數(shù)組
- 將多維數(shù)組傳遞給函數(shù)時(shí),真正傳遞的是指向數(shù)組首元素的指針
- 數(shù)組第二維(以及后面所有維度)的大小都是數(shù)組類型的一部分不能省略
void print(int (*matrix)[10],int rowSize){...}//matrix指向含有10個(gè)整數(shù)的數(shù)組的指針
void print(int matrix[][10],int rowSize){...}//與上式等價(jià)
6.2.5 main處理命令行選項(xiàng)
//argc表示數(shù)組中字符串的數(shù)量 argv是一個(gè)數(shù)組它的元素是指向C風(fēng)格字符串的指針
int main(int argc,char *argv[]){...}
//與上式等效 其中argv指向cahr* argv的第一個(gè)元素指向程序的名字或者一個(gè)空字符串
//接下來(lái)的元素依次傳遞命令行提供的實(shí)參 最后一個(gè)指針之后的元素值保證為0
int main(int argc,char **argv){...}
6.2.6 含可變形參的函數(shù)
- 所有實(shí)參類型相同,可以傳遞一個(gè)名為
initializer_list
的標(biāo)準(zhǔn)庫(kù)類型 - 如果實(shí)參類型不同 則編寫一種特殊函數(shù) 即可變參數(shù)模板
- 特殊形參類型:省略符,可傳遞可變數(shù)量實(shí)參
initializer_list
形參- 實(shí)參數(shù)量未知,但全部實(shí)參的類型都相同
- 用于表示某種特定類型的值的數(shù)組
- 是一種模板類型 但對(duì)象中的元素永遠(yuǎn)是常量值 無(wú)法修改對(duì)象元素的值
initializer_list
包含begin和end成員,可以使用范圍for循環(huán)
| initializer_list 提供的操作 |
---|
initializer_listlst; | 默認(rèn)初始化;T 類型元素的空列表 |
initializer_listlst{a,b,c...}; | lst 的元素?cái)?shù)量和初始值一樣多;lst 的元素是對(duì)應(yīng)初始值的副本;列表中的元素是const 。 |
lst2(lst) | 拷貝或賦值一個(gè)initializer_list 對(duì)象不會(huì)拷貝列表中的元素;拷貝后,原始列表和副本共享元素 |
lst2 = lst | - |
lst.size() | 列表中的元素?cái)?shù)量 |
lst.begin() | 返回指向lst 中首元素的指針 |
lst.end() | 返回指向lst 中微元素下一位置的指針 |
- 省略符形參
- 便于c++程序訪問某些特殊C代碼設(shè)置的,這些代碼使用名為varags的C標(biāo)準(zhǔn)庫(kù)功能
- 僅適用于c和c++通用的類型,大多數(shù)類類型對(duì)象傳遞省略符形參時(shí)都無(wú)法正確拷貝
- 省略符形參只能出現(xiàn)在形參列表最后一個(gè)位置
- 省略符形參無(wú)需類型檢查
6.3 返回類型和return語(yǔ)句
- return語(yǔ)句終止當(dāng)前正在執(zhí)行的函數(shù)并將控制權(quán)返回到調(diào)用該函數(shù)的地方
- 兩種形式
return;
和return expression;
6.3.1 無(wú)返回值函數(shù)
- 只能用于返回類型是void的函數(shù),返回void的函數(shù)不要求非有return因?yàn)檫@類函數(shù)最后一句會(huì)隱式執(zhí)行return
- 如果在void函數(shù)中間位置提前退出可以使用return
- 返回類型為void的函數(shù)return語(yǔ)句若有expression必須是另一個(gè)返回void的函數(shù)
6.3.2 有返回值函數(shù)
- 只要函數(shù)返回值不是void,return就必須返回一個(gè)值,返回值類型必須相同或者能隱式地轉(zhuǎn)換為函數(shù)的返回類型
- 在含有return語(yǔ)句的循環(huán)后面應(yīng)該也有一條return語(yǔ)句
- 值是如何被返回的
- 返回一個(gè)值的方式和初始化一個(gè)變量或形參的方式完全一樣
- 不要返回局部對(duì)象的引用或者指針
- 函數(shù)終止意味著局部變量的引用將指向不再有效的內(nèi)存區(qū)域
- 返回類類型的函數(shù)和調(diào)用運(yùn)算符
- 調(diào)用運(yùn)算符的優(yōu)先級(jí)與點(diǎn)運(yùn)算符和箭頭運(yùn)算符相同,且也符合左結(jié)合律
- 引用返回左值
- 調(diào)用一個(gè)返回引用的函數(shù)得到左值,其他返回類型得到右值
- 可以像使用其他左值那樣來(lái)使用返回引用的函數(shù)的調(diào)用,并且能夠?yàn)榉祷仡愋褪欠浅A恳玫暮瘮?shù)的結(jié)果賦值,如果返回類型是常量引用則不能給調(diào)用的結(jié)果賦值
- 列表初始化返回值
- 函數(shù)可以返回花括號(hào)包圍的值的列表,用來(lái)對(duì)表示函數(shù)返回的臨時(shí)量進(jìn)行初始化
- 如果列表為空,臨時(shí)量執(zhí)行值初始化,否則返回的值由返回類型決定
- 如果函數(shù)返回內(nèi)置類型,則花括號(hào)包圍列表最多包含一個(gè)值,而且該值所占空間不應(yīng)該大于目標(biāo)類型的空間;如果返回的是類類型,由類本身定義初始值如何使用
- 主函數(shù)main的返回值
- 允許main函數(shù)沒有return語(yǔ)句直接結(jié)束,控制到達(dá)結(jié)尾也沒return語(yǔ)句編譯器將隱式地插入一條返回0的return語(yǔ)句
- cstdlib頭文件定義了兩個(gè)預(yù)處理變量,表示成功與失敗,因?yàn)槭穷A(yù)處理變量所以不能在前面加std::,也不能在using聲明中出現(xiàn)
- 遞歸
- 一個(gè)函數(shù)調(diào)用它自身,一定有某條路徑是不包含遞歸調(diào)用的
- 遞歸循環(huán)
- 函數(shù)不斷調(diào)用它自身直到程序??臻g耗盡為止
- main函數(shù)不能調(diào)用它自己
6.3.3 返回?cái)?shù)組指針
- 數(shù)組不能被拷貝,所以函數(shù)不能返回?cái)?shù)組,不過(guò)可以返回?cái)?shù)組的指針或引用
- 可以使用類型別名簡(jiǎn)化返回?cái)?shù)組的指針或者引用
- 聲明一個(gè)返回?cái)?shù)組指針的函數(shù)
- 想定義一個(gè)返回?cái)?shù)組指針的函數(shù),數(shù)組維度必須跟在函數(shù)名字之后
- 函數(shù)的形參列表也跟在函數(shù)名字后面并且形參列表應(yīng)該先于數(shù)組的維度
Type (*function(parameter_list))[dimension]
- 使用尾置返回類型
- 跟在形參列表后面并且以一個(gè)
->
符號(hào)開頭 - 如
auto func(int i)->int(*)[10]
- 使用decltype
- 已知函數(shù)返回的指針將指向哪個(gè)數(shù)組,就可以使用decltype關(guān)鍵字聲明返回類型
- decltype并不負(fù)責(zé)把數(shù)組類型轉(zhuǎn)換成對(duì)應(yīng)的指針,所以decltype的結(jié)果是一個(gè)數(shù)組,要想表示返回指針還需在函數(shù)聲明時(shí)加一個(gè)*
6.4 函數(shù)重載
- 同一作用域內(nèi)幾個(gè)函數(shù)名字相同但形參列表不同
- 編譯器會(huì)根據(jù)傳遞的實(shí)參類型推斷想要的函數(shù)
- main函數(shù)不能重載
- 定義重載函數(shù)
- 重載函數(shù) 形參數(shù)量或者形參類型上有所不同
- 不允許兩個(gè)函數(shù)除了返回類型外其他所有的要素都相同
- 判斷兩個(gè)形參的類型是否相異
- 形參名字僅起到助記的作用 有沒有它并不影響形參列表的內(nèi)容
- 使用類型別名本質(zhì)上形參列表也沒什么不同
- 重載和const形參
- 頂層const不影響傳入函數(shù)的對(duì)象(一個(gè)有頂層const的形參無(wú)法和另一個(gè)沒有頂層const的形參區(qū)分開來(lái))
- 若形參是某種類型的指針或引用,則通過(guò)區(qū)分其指向的是常量對(duì)象還是非常量對(duì)象可以實(shí)現(xiàn)函數(shù)重載,此時(shí)const是底層的。編譯器可以通過(guò)實(shí)參是否是常量來(lái)推斷應(yīng)該調(diào)用哪個(gè)函數(shù)
- const不能轉(zhuǎn)換為其他類型,但非常量可以轉(zhuǎn)換為const。當(dāng)傳遞一個(gè)非常量對(duì)象或者指向非常量對(duì)象的指針時(shí),編譯器會(huì)優(yōu)先選用非常量版本的函數(shù)
- 是否重載函數(shù)要看哪個(gè)更容易理解
- const_cast和重載
- 當(dāng)實(shí)參不是常量時(shí)首先將實(shí)參強(qiáng)制轉(zhuǎn)換為對(duì)const的引用,然后調(diào)用函數(shù)的const版本,const版本返回對(duì)const type的引用,這個(gè)引用實(shí)際綁定在了某個(gè)初始的非常量實(shí)參上,因此可以將其轉(zhuǎn)換回一個(gè)普通的type& 這是安全的
- 調(diào)用重載的函數(shù)
- 函數(shù)匹配/重載確定:把函數(shù)調(diào)用與一組重載函數(shù)中的某一個(gè)關(guān)聯(lián)起來(lái)(參數(shù)數(shù)量不同/參數(shù)類型無(wú)關(guān))
- 重載函數(shù)三種可能:
- 最佳匹配
- 無(wú)匹配:找不到任何一個(gè)函數(shù)與調(diào)用的實(shí)參匹配
- 二義性調(diào)用:有多余一個(gè)函數(shù)可以匹配,但每一個(gè)都不是明顯的最佳選擇
6.4.1 重載與作用域
- 如果在內(nèi)層作用域中聲明名字,它將隱藏外層作用域中聲明的同名實(shí)體。在不同的作用域中無(wú)法重載函數(shù)名
- 一旦在作用域中找到了所需的名字,編譯器就會(huì)忽略掉外層作用域中的同名實(shí)體,然后檢測(cè)函數(shù)調(diào)用是否有效
- c++名字查找發(fā)生在類型檢查之前
6.5 特殊用途語(yǔ)言特性
- 函數(shù)相關(guān)語(yǔ)言特性:默認(rèn)實(shí)參/內(nèi)聯(lián)函數(shù)/constexpr函數(shù)
6.5.1 默認(rèn)實(shí)參
- 默認(rèn)實(shí)參:在函數(shù)的很多次調(diào)用中都被賦予一個(gè)相同的值,在調(diào)用含默認(rèn)實(shí)參的函數(shù)時(shí),可以包含該實(shí)參也可以省略該實(shí)參。
- 可以定義一個(gè)或多個(gè)形參定義默認(rèn)值,一旦某個(gè)形參被賦予了默認(rèn)值,它后面的所有形參都必須有默認(rèn)值
- 使用默認(rèn)實(shí)參調(diào)用函數(shù)
- 在調(diào)用函數(shù)時(shí)省略該實(shí)參就行
- 函數(shù)調(diào)用實(shí)參按位置解析,默認(rèn)實(shí)參負(fù)責(zé)填補(bǔ)函數(shù)調(diào)用缺少的尾部實(shí)參
- 合理設(shè)置形參的順序,讓不怎么使用默認(rèn)值的形參出現(xiàn)在前面,讓經(jīng)常使用默認(rèn)值的形參出現(xiàn)在后面
- 默認(rèn)實(shí)參聲明
- 在給定作用域中一個(gè)形參只能被賦予一次默認(rèn)實(shí)參,函數(shù)后續(xù)聲明只能為之前沒有默認(rèn)值的形參添加默認(rèn)實(shí)參,且該形參右側(cè)所有形參都必須有默認(rèn)值
- 通常應(yīng)該在函數(shù)聲明中指定默認(rèn)實(shí)參,并將聲明放在合適的頭文件中
- 默認(rèn)實(shí)參初始值
- 局部變量不能作為默認(rèn)實(shí)參,除此之外,只要表達(dá)式類型能夠轉(zhuǎn)換成形參所需的類型,該表達(dá)式就能作為默認(rèn)形參
- 用作默認(rèn)實(shí)參的名字在函數(shù)聲明所在作用域內(nèi)解析,求值過(guò)程發(fā)生在函數(shù)調(diào)用時(shí)
6.5.2 內(nèi)聯(lián)函數(shù)和constexpr函數(shù)
- 定義為函數(shù)的好處:
- 容易閱讀理解
- 確保行為的統(tǒng)一
- 修改函數(shù)比等價(jià)表達(dá)式容易
- 可以被重復(fù)利用
- 缺點(diǎn):
- 函數(shù)比求等價(jià)表達(dá)式的值要慢一些
- 函數(shù)調(diào)用包括:
- 調(diào)用前保存寄存器,返回時(shí)恢復(fù)
- 可能需要拷貝實(shí)參
- 程序轉(zhuǎn)向一個(gè)新的位置繼續(xù)執(zhí)行
- 內(nèi)聯(lián)函數(shù)可避免函數(shù)調(diào)用的開銷
- inline 讓函數(shù)在調(diào)用點(diǎn)內(nèi)聯(lián)地展開可消除函數(shù)運(yùn)行時(shí)的開銷
- 內(nèi)聯(lián)函數(shù)只是向編譯器發(fā)出的一個(gè)請(qǐng)求,編譯器可以選擇忽略
- 內(nèi)聯(lián)機(jī)制用于優(yōu)化規(guī)模較小、流程直接、頻繁調(diào)用的函數(shù)
- 很多編譯器都不支持內(nèi)聯(lián)遞歸函數(shù)
- constexpr函數(shù)
- 用于常量表達(dá)式的函數(shù),返回類型以及所有形參的類型都得是字面值類型,函數(shù)體中有且只有一條return語(yǔ)句
- constexpr函數(shù)被隱式地指定為內(nèi)聯(lián)函數(shù)
- constexpr函數(shù)不一定返回常量表達(dá)式
- 把內(nèi)聯(lián)函數(shù)和constexpr函數(shù)放在頭文件內(nèi)
- 內(nèi)聯(lián)函數(shù)和constexpr函數(shù)可以在程序中多次定義,但多個(gè)定義必須完全一致,通常定義于頭文件中
6.5.3 調(diào)試幫助
- 頭文件保護(hù)等,程序可包含一些用于調(diào)試的代碼,但只在開發(fā)時(shí)使用,發(fā)布時(shí)屏蔽掉。兩項(xiàng)預(yù)處理功能:assert和NDEBUG
- assert預(yù)處理宏
- 預(yù)處理名字由預(yù)處理器而非編譯器管理,可以直接使用預(yù)處理名字而無(wú)須提供using聲明。與預(yù)處理變量一樣,宏名字在程序內(nèi)必須唯一。
assert(expr)
如果表達(dá)式為假,assert輸出信息并終止程序的執(zhí)行,如果表達(dá)式為真則什么也不做- assert宏常用于檢查 不能發(fā)生 的條件
- NDEBUG預(yù)處理變量
- 如果定義了NDEBUG,assert什么也不做;如果沒定義NDEBUG則assert將執(zhí)行運(yùn)行時(shí)檢查
- 使用
#define NDEBUG
關(guān)閉調(diào)試狀態(tài) - 定義自己的調(diào)試代碼,若未定義NDEBUG則執(zhí)行
#ifndef和#endif
之間的代碼;若定義了NDEBUG則這些代碼被忽略掉 - c++編譯器定義
- 預(yù)處理器定義程序調(diào)試時(shí)有用的名字
_ _FILE_ _
文件名字符串字面值_ _LINE_ _
當(dāng)前行號(hào)整型字面值_ _TIME_ _
編譯時(shí)間字符串字面值_ _DATE_ _
編譯日期字符串字面值
6.6 函數(shù)匹配
- 當(dāng)函數(shù)形參數(shù)量相等以及某些形參的類型可以由其他類型轉(zhuǎn)換得來(lái)時(shí)如何確定重載函數(shù)
- 確定候選函數(shù)和可行函數(shù)
- 候選函數(shù):與被調(diào)用函數(shù)同名;聲明在調(diào)用點(diǎn)可見
- 可行函數(shù):形參數(shù)量與本次提供的實(shí)參數(shù)量相等;每個(gè)實(shí)參類型與形參類型相同或能夠轉(zhuǎn)換為形參的類型
- 如果沒找到可行函數(shù),編譯器將報(bào)告無(wú)匹配函數(shù)的錯(cuò)誤
- 尋找最佳匹配
- 逐一檢查函數(shù)提供的實(shí)參,尋找形參類型與實(shí)參類型最匹配的那個(gè)可行函數(shù)
- 實(shí)參與形參類型越接近則匹配的越好;精確匹配比需要類型轉(zhuǎn)換的匹配更好
- 含有多個(gè)形參的函數(shù)匹配
- 編譯器選擇形參數(shù)量滿足要求且實(shí)參類型和形參類型能夠相匹配的函數(shù),依次檢查每個(gè)實(shí)參以確定哪個(gè)函數(shù)是最佳匹配,如果有且只有一個(gè)函數(shù)滿足下列要求,則匹配成功
- 該函數(shù)每個(gè)實(shí)參的匹配都不劣于其他可行函數(shù)需要的匹配
- 至少有一個(gè)實(shí)參的匹配優(yōu)于其他可行函數(shù)提供的匹配
- 調(diào)用重載時(shí)應(yīng)該盡量避免強(qiáng)制類型轉(zhuǎn)換,形參設(shè)計(jì)的合理性
6.6.1 實(shí)參類型轉(zhuǎn)換
- 實(shí)參到形參的類型轉(zhuǎn)換等級(jí)
- 精確匹配
- 實(shí)參類型和形參類型相同
- 實(shí)參從數(shù)組或函數(shù)類型轉(zhuǎn)換為對(duì)應(yīng)指針類型
- 向?qū)崊⑻砑禹攲觕onst或者從實(shí)參中刪除頂層const
- const轉(zhuǎn)換實(shí)現(xiàn)的匹配
- 類型提升實(shí)現(xiàn)的匹配
- 算術(shù)類型轉(zhuǎn)換/指針轉(zhuǎn)換
- 類類型轉(zhuǎn)換
- 需要類型提升和算術(shù)類型轉(zhuǎn)換的匹配
- 小整形提升到int類型或者更大的整數(shù)類型
- 存在兩種可能的算術(shù)類型轉(zhuǎn)換時(shí)調(diào)用具有二義性
- 函數(shù)匹配和const實(shí)參
- 調(diào)用時(shí)編譯器通過(guò)實(shí)參是否是常量來(lái)決定選擇哪個(gè)函數(shù)
- 不能將普通引用綁定到const對(duì)象上
- 非常量對(duì)象可用于初始化常量引用和非常量引用,但非常量對(duì)象初始化常量引用需要類型轉(zhuǎn)換,出于精確匹配的目的選用非常量版本的函數(shù)
6.7 函數(shù)指針
- 函數(shù)指針指向特定類型,函數(shù)類型由它的返回值類型和形參類型共同決定,與函數(shù)名無(wú)關(guān)
- 想聲明一個(gè)可以指向該函數(shù)的指針,只需用指針替換函數(shù)名,如
bool (*pf)(const string&,const string&);
//pf前有一個(gè)*,故pf為指針,右側(cè)為形參列表,表示pf指向的是函數(shù),左側(cè)函數(shù)返回值是布爾值
//pf指向一個(gè)形參是兩個(gè)const string的引用,返回類型是bool的函數(shù)
//*pf兩端的括號(hào)不可少,不加括號(hào)的話則pf是一個(gè)返回值為bool指針的函數(shù)
- 使用函數(shù)指針
- 將函數(shù)名作為值使用時(shí),函數(shù)自動(dòng)轉(zhuǎn)換為指針
- 直接使用只愛那個(gè)函數(shù)的指針調(diào)用函數(shù)可無(wú)須提前解引用
- 指向不同函數(shù)類型的指針間不存在轉(zhuǎn)換規(guī)則,但可以為函數(shù)指針賦值nulllptr或0,表示該指針沒有指向任何一個(gè)函數(shù)
- 重載函數(shù)的指針
- 編譯器通過(guò)指針類型決定選用哪個(gè)函數(shù),指針類型必須與重載函數(shù)中的某一個(gè)精確匹配
- 函數(shù)指針形參
- 雖然不能定義數(shù)組和函數(shù)類型的形參。但形參可以是指向函數(shù)的指針
- 形參看起來(lái)像是函數(shù)類型,實(shí)際上是當(dāng)成指針使用
- 可以直接把函數(shù)當(dāng)作實(shí)參使用,它自動(dòng)轉(zhuǎn)換成指針
- 類型別名可用于簡(jiǎn)化使用函數(shù)的指針,如
//Func和Func2是函數(shù)類型
//調(diào)用Func作為參數(shù)時(shí)編譯器自動(dòng)將Func表示的函數(shù)類型轉(zhuǎn)換為指針
typedef bool Func(const string&,const string&);
typedef decltype(lengthCompare) Func2;//與上式等價(jià)
//FuncP和FuncP2是指向函數(shù)的指針
typedef bool (*FuncP)(const string&,const string&);
typedef decltype(lengthCompare) *FuncP2;//與上式等價(jià)
//decltype返回函數(shù)類型,不會(huì)自動(dòng)將函數(shù)類型轉(zhuǎn)換為指針類型,只有在結(jié)果前面加*才能得到指針
- 返回指向函數(shù)的指針
- 和數(shù)組類似,雖然不能返回一個(gè)函數(shù),但能夠返回指向函數(shù)類型的指針,必須把返回值類型寫成指針形式
- 通過(guò)類型別名可以某符號(hào)定義成函數(shù)或者指向函數(shù)的指針類型
- 和函數(shù)類型的形參不一樣,返回類型不會(huì)自動(dòng)地轉(zhuǎn)換成指針,必須顯示地將返回類型指定為指針
- 可以使用尾置返回類型的方式聲明一個(gè)返回函數(shù)指針的函數(shù)
- 將auto和decltype用于函數(shù)指針指針類型
- 明確知道返回函數(shù)是哪一個(gè)就能使用decltype簡(jiǎn)化函數(shù)指針返回類型
- 將decltype作用于某個(gè)函數(shù)時(shí),它返回的是函數(shù)類型而非指針類型,需要顯示地加上*以表明我們需要返回的指針而非函數(shù)本身。
小結(jié)
- 函數(shù):命名了的計(jì)算單元,對(duì)程序結(jié)構(gòu)化至關(guān)重要
- 函數(shù)包含:返回類型/名字/形參列表/函數(shù)體
- 函數(shù)可以被重載:同一個(gè)名字可用于定義多個(gè)函數(shù),只要形參數(shù)量或類型不同就行,編譯器自動(dòng)選定被調(diào)用函數(shù)
- 函數(shù)匹配:從一組重載函數(shù)中選取最佳函數(shù)
術(shù)語(yǔ)表
- 二義性調(diào)用:函數(shù)在匹配時(shí)兩個(gè)或多個(gè)函數(shù)提供的匹配一樣好,編譯器找不到唯一的最佳匹配
- 自動(dòng)對(duì)象:僅存在于函數(shù)執(zhí)行過(guò)程中的對(duì)象。當(dāng)程序控制流經(jīng)過(guò)此類對(duì)象定義語(yǔ)句時(shí)創(chuàng)建該對(duì)象,當(dāng)?shù)竭_(dá)定義所在塊末尾時(shí)銷毀該對(duì)象
- 函數(shù)原型:函數(shù)聲明包含返回類型/名字/形參類型
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)站題目:c++primer第6章函數(shù)-創(chuàng)新互聯(lián)
新聞來(lái)源:http://jinyejixie.com/article4/ddshie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、外貿(mào)建站、建站公司、網(wǎng)站維護(hù)、App開發(fā)、網(wǎng)站設(shè)計(jì)公司
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源:
創(chuàng)新互聯(lián)