C++ primer第六章6.5函数的学习 之特殊用途的语言特性
生活随笔
收集整理的這篇文章主要介紹了
C++ primer第六章6.5函数的学习 之特殊用途的语言特性
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
6.5.1 默認(rèn)實(shí)參
- 將反復(fù)出現(xiàn)的數(shù)值稱為函數(shù)的默認(rèn)實(shí)參,調(diào)用含有默認(rèn)實(shí)參的時(shí)候可以包含該實(shí)參也可以不包含
- 比如程序打開頁面會(huì)有一個(gè)默認(rèn)的寬高,如果用戶不喜歡也允許用戶自由指定與默認(rèn)數(shù)值不同的數(shù)值,具體例子如下圖所示
- 默認(rèn)實(shí)參作為形參的初始化數(shù)值出現(xiàn)在形參列表中,可以為一個(gè)或者多個(gè)形參定義成默認(rèn)數(shù)值,但是,一旦某個(gè)形參被賦予了默認(rèn)數(shù)值,這個(gè)形參之后的數(shù)值也必須有默認(rèn)數(shù)值。
使用默認(rèn)實(shí)參調(diào)用函數(shù)
- 如果使用默認(rèn)的實(shí)參,調(diào)用函數(shù)的時(shí)候省略掉該實(shí)參就可以了。
- 如上面提出的screen函數(shù),有三個(gè)變量,因此可以使用0、1、2、3個(gè)實(shí)參調(diào)用該函數(shù)
- window = screen(,,'&');//錯(cuò)誤,只可以忽略掉尾部的實(shí)參,即左邊的必須補(bǔ)齊定義,只有右邊的才可以缺省
- 因此,在實(shí)際使用的場景中,需要設(shè)計(jì)形參的順序,將不怎么使用默認(rèn)形參的變量放在前面
默認(rèn)實(shí)參聲明
- 對于函數(shù)的聲明來講,通常是將其放在頭文件中,并且每個(gè)函數(shù)聲明一次,但是多次聲明也是合法的。
- 但是,在給定的作用域中,一個(gè)形參只可以賦予一次默認(rèn)實(shí)參。即,函數(shù)的后續(xù)聲明只能為之前那些沒有默認(rèn)值的形參添加默認(rèn)的實(shí)參,而且這個(gè)形參的左側(cè)的所有的形參都有默認(rèn)值。
默認(rèn)實(shí)參初始值
- 局部變量不可以作為默認(rèn)的實(shí)參,只要表達(dá)式的類型可以轉(zhuǎn)化為形參所需要的類型,該表達(dá)式就可以作為默認(rèn)的實(shí)參。
- 用作默認(rèn)實(shí)參的名字,在函數(shù)聲明所在的作用域中解析,而這些名字的求值的過程發(fā)生在函數(shù)調(diào)用的時(shí)候
- 在函數(shù)f2的內(nèi)部改變了def的值,所以對于screen的調(diào)用將會(huì)傳遞這個(gè)更新過的數(shù)值。
- 對于wd,內(nèi)部聲明的局部變量會(huì)隱藏外部的wd,但是該局部變量并不會(huì)傳遞給screen的默認(rèn)的參數(shù)
6.5.2 內(nèi)聯(lián)函數(shù)和constexpr函數(shù)
定義函數(shù)的好處
- 使用函數(shù)可以確保行為的統(tǒng)一,每次相關(guān)的操作都按照同樣的方式進(jìn)行
- 如果需要修改計(jì)算的過程,顯然修改函數(shù)比先找到等價(jià)的表達(dá)式所有出現(xiàn)地方再逐一修改更加方便
- 函數(shù)可以被其他應(yīng)用重復(fù)調(diào)用,省去了重新編寫開發(fā)的代價(jià)
壞處
- 調(diào)用函數(shù)會(huì)比使用表達(dá)式慢,因?yàn)槭褂煤瘮?shù)要涉及到一系列的工作:調(diào)用前保存寄存器、并且在返回的是會(huì)恢復(fù);需要拷貝實(shí)參,程序需要在不同的新的位置上繼續(xù)執(zhí)行。
內(nèi)聯(lián)函數(shù)可以避免函數(shù)的調(diào)用所帶來的開銷
- 將函數(shù)指定為內(nèi)聯(lián)函數(shù),通常是將它在每一個(gè)調(diào)用點(diǎn)上“內(nèi)聯(lián)地”展開,將會(huì)減少函數(shù)運(yùn)行使得開銷。
- 在函數(shù)的前面加上關(guān)鍵字inline就可以將其聲明稱為內(nèi)聯(lián)函數(shù)
- 內(nèi)聯(lián)說明只是向編譯器發(fā)出一個(gè)請求,編譯器可以選擇忽略這個(gè)請求
- 內(nèi)聯(lián)機(jī)制一般用于優(yōu)化規(guī)模較小,流程直接、頻繁調(diào)用的函數(shù),很多編譯器都不支持內(nèi)聯(lián)遞歸函數(shù),如果程序很大的話,也不大可能在調(diào)用點(diǎn)內(nèi)聯(lián)的展開
constexpr函數(shù)
- constexpr是指可以用于常量表達(dá)式的函數(shù)。
- 其函數(shù)的返回類型以及所有的形參的類型都得是字面值類型,而且函數(shù)體中必須有且只有一個(gè)return語句。
- 把new_sz定義成無參數(shù)的constexpr函數(shù),因?yàn)榫幾g器能在程序編譯的時(shí)候驗(yàn)證new_sz函數(shù)返回的是常量的表達(dá)式,所以可以使用new_sz來初始化foo函數(shù)。
- 執(zhí)行該初始化任務(wù)的時(shí)候,編譯器把constexpr函數(shù)的調(diào)用替換成其結(jié)果數(shù)值。為了能在編譯的過程中隨時(shí)展開,constexpr會(huì)被隱式轉(zhuǎn)變?yōu)閮?nèi)聯(lián)函數(shù)。
- constexpr函數(shù)體內(nèi)也可以包含其他語句,只要這些語句在運(yùn)行的時(shí)候不執(zhí)行任何操作就可以。例如,constexpr函數(shù)內(nèi)可以有空的語句、類型別名以及using聲明。
- 允許constexpr函數(shù)的返回值并非一個(gè)常量。
把內(nèi)聯(lián)函數(shù)和constexpr函數(shù)放在頭文件中
- 和其他函數(shù)不一樣,內(nèi)聯(lián)函數(shù)和constexpr函數(shù)可以在程序中多次定義。畢竟,編譯器要想展開函數(shù)僅僅有函數(shù)的聲明是不夠的,還需要函數(shù)的定義。但是對于某個(gè)給定的內(nèi)聯(lián)函數(shù)或者constexpr函數(shù)來說,他的多個(gè)定義必須完全一致,因此通常將他們定義在頭文件中。
6.5.3 調(diào)試幫助
- C++有些時(shí)候會(huì)用到一些類似于頭文件保護(hù)的技術(shù),從而可以有選擇的執(zhí)行代碼。
- 基本思想是,程序包含一些用于調(diào)試的代碼,但是這些代碼只會(huì)在開發(fā)程序的時(shí)候使用,當(dāng)程序完準(zhǔn)備上線的時(shí)候,需要先屏蔽代碼,這就用到了兩項(xiàng)預(yù)先處理的功能:assert和NDEBUG
assert預(yù)處理宏
- 預(yù)處理宏就是一個(gè)預(yù)處理變量,其行為類似于內(nèi)聯(lián)函數(shù)
- assert使用一個(gè)表達(dá)式作為它的條件 assert(expr);? 首先對于expr進(jìn)行求值,如果表達(dá)式為假,assert會(huì)輸出信息并且終止程序的執(zhí)行。如果表達(dá)式為真,assert什么也不做
- assert的頭文件會(huì)定義在cassert文件中,因?yàn)轭A(yù)處理名字是由預(yù)處理器而不是編譯管理,因此可以直接使用預(yù)處理名字而不需要提供using聲明。即直接使用assert,而不是std::assert,也不需要為assert提供using的聲明。
- 和預(yù)處理的變量一樣,宏名字在程序內(nèi)部必須唯一。但是在實(shí)際編程的時(shí)候,即使沒有包含這個(gè)頭文件,也不要使用assert這個(gè)名字進(jìn)行任何相關(guān)的變量、函數(shù)、其他實(shí)體等的命名,因?yàn)?#xff0c;很多頭文件都會(huì)包含這個(gè)cassert,有可能通過其他途徑包含在程序中。
- assert宏常常用于檢查“不能發(fā)生的條件”。例如,一個(gè)對于輸入文本進(jìn)行操作的語句對于輸入的長度有很大的要求,必須大于某一個(gè)指定的閾值。這個(gè)使用,程序可能會(huì)包含一個(gè)如下所示的語句? assert(word.size() > threshold );
- assert都是一種調(diào)試程序的輔助手段,但是他不可以替代運(yùn)行時(shí)候的邏輯檢查,也不可以替代程序本身應(yīng)該包含的錯(cuò)誤檢查
NDEBUG預(yù)處理變量
- assert的行為依賴于一個(gè)名為NDEBUG的預(yù)處理變量的狀態(tài)。如果定義了NDEBUG,那么assert就什么都不做。默認(rèn)情況下是沒有定義這個(gè)NDEBUG的,因此assert會(huì)執(zhí)行運(yùn)行檢查。
- 使用#define NDEBUG 或者使用命令行進(jìn)行程序編譯的時(shí)候,使用 CC -D NDEBUG main.c 這兩者之間是等效的
- 同理,也可以使用NDEBUG來編寫自己的條件調(diào)試的代碼,如果NDEBUG沒有定義,那么將會(huì)執(zhí)行#ifdef和#endif之間的代碼;如果定義了NDEBUG,那么這些代碼將會(huì)被忽略掉
- #define NDEBUG
- __func__是一個(gè)const char的一個(gè)靜態(tài)數(shù)組,用于存放函數(shù)的名字
總結(jié)
以上是生活随笔為你收集整理的C++ primer第六章6.5函数的学习 之特殊用途的语言特性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Tftpd64工具将文件系统烧录到l
- 下一篇: C++ Map简单介绍 ,比如添加元素、