默認(rèn)參數(shù)
- C++允許函數(shù)設(shè)置默認(rèn)參數(shù),調(diào)用時(shí)根據(jù)情況省略實(shí)參:
- 默認(rèn)函數(shù)只能按照右到左的順序
- 如果函數(shù)同時(shí)有聲明、實(shí)現(xiàn),默認(rèn)參數(shù)是能放在函數(shù)聲明中
- 默認(rèn)參數(shù)的值可以是常量、全局符號(hào)(全局變量,函數(shù)名)
int age = 33;
void test() {
cout << "test()" << endl;
}
void display(int a = 11, int b = 22, int c = age, void (*func)() = test) {
cout << "a is " << a << endl;
cout << "b is " << b << endl;
cout << "c is " << c << endl;
}
int main() {
display()
return 0;
}
-
函數(shù)重載、默認(rèn)參數(shù)可能會(huì)產(chǎn)生沖突、二義性(建議優(yōu)先選擇使用默認(rèn)參數(shù))
底層分析:
1.沒有默認(rèn)參數(shù)情況查看匯編:
int sum(int v1, int v2) {
return v1 + v2;
}
int main() {
sum(1, 2);
sum(3, 4);
}


2.有默認(rèn)參數(shù):

兩種猜測(cè):
猜測(cè)1:
sum(1, 4)
猜測(cè)2:
int sum(int v1, int v2) {
v2 = 4 ; return v1+v2;
}
匯編:




- E8 : 函數(shù)調(diào)用
- 為什么后面機(jī)器碼不一樣
后面這個(gè)是根據(jù)地址算出來的值, 所以機(jī)器碼有一點(diǎn)點(diǎn)不一樣 (只是機(jī)器指令的位置不一樣 ,也可以認(rèn)為是返回值地址)不用糾結(jié)

extern “C”
- 被 extern “C” 修飾的代碼會(huì)按照C語(yǔ)言的方式去編譯


- 兩種寫法
extern “C” void func() {
cout << "func()" << endl;
}
extern “C” void func(int age) {
cout << "func(int age)" << age << endl;
}
extern “C” {
void func() {
cout << "func()" << endl;
}
void func(int age) {
cout << "func(int age)" << age << endl;
}
}
- 如果函數(shù)同時(shí)有聲明和實(shí)現(xiàn),要讓函數(shù)聲明被extern ”C“修飾,函數(shù)實(shí)現(xiàn)可以不修飾

最終編譯時(shí)函數(shù)名不同,所以不報(bào)錯(cuò),可以同時(shí)存在
-
用于C、C++混合開發(fā):
1.編譯方式不一樣,沒法直接找到調(diào)用:
2.聲明上加上extern “C”: 告訴編譯器 用C語(yǔ)言方式編譯的對(duì)應(yīng)的函數(shù)

3.第三方庫(kù):函數(shù)聲明.h文件, 函數(shù)實(shí)現(xiàn).c文件

4.把頭文件包含進(jìn)去就可以了,include相當(dāng)于把文件內(nèi)容拷貝進(jìn)去

5.直接加.h里面,這樣更方便

6.如果C語(yǔ)言也要調(diào)用呢? 報(bào)錯(cuò): 因?yàn)镃語(yǔ)言環(huán)境 不認(rèn)識(shí) extern “C”

7.希望C++環(huán)境自動(dòng)加上extern c, C語(yǔ)言環(huán)境不加:
C++ 環(huán)境編譯器默認(rèn)有個(gè)宏定義 :可以用這個(gè)宏判斷是否是C++環(huán)境

利用這個(gè)宏 條件編譯:

8.重復(fù)包含頭文件造成浪費(fèi)

利用宏判斷:如果沒定義過ABC 定義ABC
#ifndef ABC
#define ABC
...
#endif ABC
萬(wàn)一其他文件也用到相同的宏定義會(huì)出問題:

故為保證每個(gè)頭文件里面的宏都是唯一的,用文件名:__MATH, __OTHER
9.自動(dòng)防止頭文件被重復(fù)包含:

- 防止文件被重復(fù)包含
常使用#ifndef、#define、#endif 防止頭文件被重復(fù)包含
pragma once 可以防止整個(gè)文件內(nèi)容被重復(fù)包含
區(qū)別:
1.#ifndef、#define、#endif 受C,C++標(biāo)準(zhǔn)支持,不受編譯器的限制
2.有些編譯器不支持 pragma once,較老的編譯器不支持,兼容性不夠好
3.#ifndef、#define、#endif 可以針對(duì)一個(gè)文件中的部分代碼,而pragma once只能針對(duì)整個(gè)文件
內(nèi)聯(lián)函數(shù)(inline function):
- 使用inline修飾函數(shù)的聲明或者實(shí)現(xiàn),可以使變?yōu)閮?nèi)聯(lián)函數(shù)
- 特點(diǎn)
- 編譯器會(huì)將函數(shù)調(diào)用直接展開為函數(shù)體代碼
- 可以減少函數(shù)調(diào)用開銷
- 會(huì)增大代碼嗎的體積
- 盡量不要內(nèi)聯(lián)超過10行代碼的函數(shù)
- 有些函數(shù)即使聲明了,也不定會(huì)被編譯器內(nèi)聯(lián),比如遞歸函數(shù)


調(diào)用函數(shù)代價(jià):開啟??臻g,回收??臻g
一旦變?yōu)閮?nèi)聯(lián)函數(shù): 到時(shí)候執(zhí)行這個(gè)代碼的時(shí)候不存在函數(shù)操作,不存在??臻g開辟,直接執(zhí)行代碼什么時(shí)候使用內(nèi)聯(lián)函數(shù)提高效率:1.代碼體積小 2.頻繁調(diào)用
-
窺探內(nèi)聯(lián)函數(shù)本質(zhì):
1.普通函數(shù):進(jìn)行匯編調(diào)試
2.內(nèi)聯(lián)函數(shù):
還是有函數(shù)調(diào)用,debug模式是不會(huì)有內(nèi)聯(lián)優(yōu)化的

3.變成release模式:
調(diào)試:直接調(diào)用
由于編譯器優(yōu)化 連 + 操作都沒有了 直接出現(xiàn)了30 (1E)

4.為窺探內(nèi)聯(lián):
release模式開啟禁止優(yōu)化:
內(nèi)聯(lián)函數(shù)擴(kuò)展:


不加內(nèi)聯(lián):

-
內(nèi)聯(lián)函數(shù)和宏:
推薦使用內(nèi)聯(lián)函數(shù):寫代碼的時(shí)候有語(yǔ)法檢測(cè)和提示, 函數(shù)特性(傳參)

表達(dá)式
-
C++有些表達(dá)式是可以被賦值的
Const
- const是常量的意思,被其修飾的變量不可修改
如果修飾的是類,結(jié)構(gòu)體(的指針),其成員也不可以更改
-
下面五個(gè)指針分別是什么含義:
p3:

p1,p2:

p4,p5:

const修飾的是其右邊的內(nèi)容






