《C++ Primer 第五版》(第6.3~6.7节)——返回指向数组/函数的指针,函数重载,默认形参、inline函数和constexpr函数
1.返回指向數組/函數的指針
? ? ? ? ? ?顧名思義,就是函數返回值為指向數組/函數的指針。
? ? ? ? ? ?數組的性質:不能被拷貝,函數也不能返回數組。但可以返回數組指針/引用,聲明一個返回數組指針的函數,有四種方式,一種是直接聲明,格式為:
? ? ? ? ? ? ? ? ? ? ? ? ? int? (*func(int i) [10];? ?//函數聲明
? ? ? ? ? 第二種是使用using/typedef類型別名來簡化:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?typedef? int? arr[10];? /using arr=int[10];? ? ? //定義類型別名和數組等效
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? arr?*func(int i);? //函數聲明
? ? ? ? ? 第三種是采用C++11提供的尾后返回類型的方式來聲明數組指針,具體格式如下:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?auto func(int i)? -> int(*)[10];
? ? ? ? ? 第四種是知道數組指針指向那種類型的數組情況下,可以采用decltype獲得數組類型(decltype,sizeof,typeid不會讓數組退化為指針),具體格式如下:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int array[10] = { 0 };
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?decltype(array) *func(int i);
? ? ? ? ?函數指針是采用需要聲明的指針名替換函數名來完成函數指針的聲明,函數指針由函數的返回值和參數列表類型共同決定。其聲明、賦值和調用如下所示:
? ? ? ? ? ? ? ? bool LengthCompare(const string & , const string &);? ?//函數聲明
? ? ? ? ? ? ? ? bool(*pf)(const string & , const string &);? ? ? ? ? ? ? ?//函數指針聲明
? ? ? ? ? ? ? ? ? ? ? pf=LengthCompare;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //函數指針賦值
? ? ? ? ? ? ? ? ? ? ? pf=&LengthCompare;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //函數指針賦值
? ? ? ? ? ? ? ? bool b1 = pf("hello”,“good”);? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//直接調用,等價于bool b3=LengthCompare("hello”,“good”);
? ? ? ? ? ? ? ? bool b2 = (*pf)("hello”,“good”);? ? ? ? ? ? ? ? ? ? ? ?//解引用調用
? ? ? ? 函數指針作為C語言的半壁江山,其可以作為函數的形參,來實現一類函數的功能,從來增加代碼的魯棒性。具體代碼如下:
void usebigger(const string &s1,const string&s2, bool pf(const string &,const string &));//函數指針做形參,pf替換為(*pf)一樣
? ? ? ? 使用using/typedef可以簡化上述的過程,具體代碼如下:
?typedef bool func(const string &,const string&)/typedef decltype(LengthCompare) funcz;//聲明func/funcz為函數類型;
typedef bool (*funcp)(const string &,const string&)/typedef decltype(LengthCompare)? *funcp2;//聲明funcp/funcp2函數指針類型?
void usebigger(const string&,const string&,func/funcp2);//函數形參為函數指針,函數名做形參時可做函數指針用
? ? ? ? 另外函數指針也可以作為返回值使用,具體形式為:
? ? ? ? ? ? ? ?int (* f1(int) )(int * ,? int); //聲明一個函數指針,數指針指向的是一個參數列表為int*和int,返回值為int的函數。
? ? ? ?使用尾置返回類型的方式聲明一個返回函數指針的函數,格式為:
? ? ? ? ? ? ? auto f1(int)? -> int (*)(int * , int);
2.函數重載
? ? ? ? ? 函數重載的條件:相同作用域,同名函數,不同參數列表。其中返回類型和參數列表中的頂層const不能作為函數重載的依據。如果同名函數不在同一作用域內,但在同一個文件中,則屬于函數覆蓋。
? ? ? ? ? 重載函數調用時,如有多個函數滿足,則優先考慮不用隱式轉換的版本。
? ? ? ? ? const_cast可以用于改變運算對象的底層const屬性,可以用于增加const屬性或者去除const屬性,這里很容易理解錯說const_cast只能用于去除原因對象的const屬性,《C++ Primer 第五版》p209的例子可以看出const_cast的另外一種用法。
? ? ? ? ?在查找const_cast相關博客介紹過程中,無意之間發現了一個程序中的專業名詞“常量折疊”,具體意思在編譯期間簡化常量表達式的一個過程,簡單來說就是將常量表達式計算求值,并對求得的值來替換表達式,放入常量表中,具體詳細的情況可參考博客:https://blog.csdn.net/it_wjw/article/details/86668302
3.默認形參、inline函數和constexpr函數
? ? ? ? ?函數的默認形參就是在調用時函數可以不給實參,此時函數的形參采用默認參數值,多用于某些函數參數值固定的情況。默認形參之后就不能再出現需要初始化的形參。
? ? ? ? ?內聯函數(inline函數)用于優化規模較小、流程直接、使用頻繁的函數,使用內聯函數能夠省去函數的出入棧過程和參數的拷貝過程,但是inline只是對編譯器的一個請求,編譯器可以忽略這個請求。inline函數的實質是在調用函數的地方直接把函數替換調用函數。
? ? ? ? constexpr函數:通常用于常量表達式的函數(通常會被隱式inline化)。要求:返回類型和形參類型(應該是實參的帶入值)都是字面值常量;函數體有且僅有一條return語句;函數體中的語句在運行時不執行任何操作。
? ? ? ? ?由于inline和constexpr函數都屬于函數調用時直接將函數體和調用函數替換的情形,因此inline和constexpr函數應該講定義放在頭文件中,另外這兩種函數可以在多個文件中重復定義,但必須保證多個定義完全相同。**新知識點
4.調試代碼工具
? ? ? ? ? assert(斷言,頭文件在cassert中);用于輔助驗證不可能發生的事情。assert括號中的條件為真,則對程序無影響,否則程序停止運行。
? ? ? ? ? NDENUG 預處理變量,如果定義了這個預處理變量,不執行assert,沒有定義這個預處理變量,則執行assert(默認)。
? ? ? ? ? 預處理器提供5個預處理器定義的程序調試名字:
? ? ? ? ? ? ? ? ? ? ? ?_ _ func _ _:輸出當前調試函數的名字
? ? ? ? ? ? ? ? ? ? ? ?_ _ FILE _ _:輸出當前文件名的字符串字面值
? ? ? ? ? ? ? ? ? ? ? ?_ _ LINE _ _:輸出當前行號的整型字面值
? ? ? ? ? ? ? ? ? ? ??_ _ TIME _ _:輸出當前文件編譯時間的字符串字面值
? ? ? ? ? ? ? ? ? ? ? _ _ DATE?_ _:輸出當前文件編譯日期的字符串字面值
總結
以上是生活随笔為你收集整理的《C++ Primer 第五版》(第6.3~6.7节)——返回指向数组/函数的指针,函数重载,默认形参、inline函数和constexpr函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php中递归函数里变量值的问题 财
- 下一篇: 《C++ Primer 第五版》(第1~