C++基礎(chǔ)語法-默認(rèn)參數(shù)、內(nèi)聯(lián)函數(shù)、引用

函數(shù)默認(rèn)參數(shù)

C++允許函數(shù)設(shè)置默認(rèn)參數(shù),在調(diào)用時(shí)可以根據(jù)情況省略實(shí)參。規(guī)則如下:

  • 默認(rèn)參數(shù)只能按照右到左的順序
void print(int a,int b = 100)
{
   cout << "a is " << a << endl;
   cout << "b is " << b << endl;
}
  • 如果函數(shù)同時(shí)有聲明、實(shí)現(xiàn),默認(rèn)參數(shù)只能放在函數(shù)聲明中
void print(int a,int b = 100);
int main(int argc, const char * argv[]) {
    print(10);
    return 0;
}
void print(int a,int b)
{
    cout << "a is " << a << endl;
    cout << "b is " << b << endl;
}
  • 默認(rèn)參數(shù)的值可以是常量、全局符號(hào)(全局變量、函數(shù)名)
    常量上面有所舉例,這里舉一個(gè)全局變量和函數(shù)名作為參數(shù)的列子如下代碼所示:
//定義一個(gè)全局變量
int number = 10000;
void print(int a,int b = number)
{
    cout << "a is " << a << endl;
    cout << "b is " << b << endl;
}
int main(int argc, const char * argv[]) {
    print(10);
    return 0;
}
//定義一個(gè)函數(shù)指針
typedef void(*FuncBlock)(int a,int b);
void block(int a,int b)
{
    cout << "block a is " << a << endl;
    cout << "block b is " << b << endl;
}

void print(int a,FuncBlock fun = block)
{
    cout << "a is " << a << endl;
    //利用函數(shù)指針真正調(diào)用block函數(shù)
    block(10, 10);
}
int main(int argc, const char * argv[]) {
    //調(diào)用函數(shù),函數(shù)默認(rèn)為block
    print(100);
    return 0;
}

注意:函數(shù)默認(rèn)參數(shù)可能會(huì)與函數(shù)重載會(huì)產(chǎn)生沖突,造成調(diào)用不明確,需要避免,建議優(yōu)選選擇函數(shù)默認(rèn)參數(shù)

void print(int a,int b = 100)
{
    cout << "a is " << a << endl;
    cout << "b is " << b << endl;
}
void print(int a)
{
    cout << "a is " << a << endl;
}
int main(int argc, const char * argv[]) {
    //調(diào)用錯(cuò)誤
    //call to 'print' is ambiguous
    print(100);
    return 0;
}

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

定義:使用inline修飾過的函數(shù)的聲明或者實(shí)現(xiàn),
建議聲明和實(shí)現(xiàn)都增加inline修飾。內(nèi)聯(lián)函數(shù)特點(diǎn)和注意事項(xiàng)如下:

  • 編譯器會(huì)將函數(shù)調(diào)用直接展開為函數(shù)體代碼
  • 可以減少函數(shù)調(diào)用的開銷
  • 會(huì)增大代碼體積
  • 內(nèi)聯(lián)函數(shù)盡量不要內(nèi)聯(lián)超過10行代碼的函數(shù)
  • 有些函數(shù)即使聲明為inline,也不一定會(huì)被編譯器內(nèi)聯(lián),比如遞歸函數(shù)

內(nèi)聯(lián)函數(shù)和宏,都可以減少函數(shù)調(diào)用的開銷相比宏,內(nèi)聯(lián)函數(shù)多了語法檢測(cè)和函數(shù)特性,宏只是單純的替換, 注意下以下代碼區(qū)別:

#define sum(x) (x + x)  //結(jié)果為21
inline int sum(int x) { return x + x; } //結(jié)果為20
int a = 10; sum(a++);
 

引用

引用相當(dāng)于是變量的別名,包括基本數(shù)據(jù)類型、枚舉、結(jié)構(gòu)體、類、指針、數(shù)組等,都可以有引用。我們先來看下基本類型的引用如下:

int age = 100;
int &rage = age;      //rage就是age的引用
rage = 101;//改變引用rage的值,也修改了age的值
cout << rage << endl; //101
cout << age << endl;  //101

再來看結(jié)構(gòu)體和指針的引用:

struct Person {
    int age;
};
    
//結(jié)構(gòu)體對(duì)象的引用
Person p;
Person &rp = p;
rp.age = 18;
cout << p.age << endl; //18
    
//指向結(jié)構(gòu)體對(duì)象指針的引用
Person *pp = new Person();
Person *&rpp = pp;  //pp指針的引用rpp
rpp->age = 19;
cout << pp->age << endl;  //19

數(shù)組的引用如下:

int array[] = { 10, 20, 30 };
int (&rArray)[3] = array;  //這里定義數(shù)組的引用,這里必須指明 數(shù)組元素個(gè)數(shù)
cout << rArray[0] << endl; //10

使用引用的注意事項(xiàng):

  • 引用必須初始化,且一旦初始化就不能再改變成其他變量的引用
  • 可以用引用初始化另一個(gè)引用,即存在一個(gè)變量多個(gè)別名
  • 對(duì)變量引用的操作其實(shí)就是對(duì)變量本身的操作
  • 不存在引用的引用,引用數(shù)組,指向引用的指針
//一個(gè)變量多個(gè)引用
int age = 100;
int number = 1000;
int &rage = age;         //rage就是age的引用
int &rage1 = rage;       //rage1也是age的引用
int &rage2 = age;        //rage2也是age的引用
&rage = number;        //錯(cuò)誤,引用是不能再被改變成其他變量的引用
int &arry[4];  //錯(cuò)誤,不存在引用數(shù)組
int& *rpage = rage; //錯(cuò)誤,沒有引用類型的指針
int  *page = &rage; //正確,對(duì)引用取地址其實(shí)就是對(duì)變量取地址,再用指針指向這個(gè)地址

常引用

我們都知道經(jīng)過const修飾過的變量會(huì)變成常量,跟const的位置也有關(guān),這里我們?cè)賮韽?fù)習(xí)下const修飾變量的用法:

int age = 10;
 // *p0是常量,p0不是常量(指針指向地址里面存的值不可改,指針指向地址可以改)
const int *p0 = &age;
// *p1是常量,p1不是常量(跟上述一樣)
int const *p1 = &age;
// p2是常量,*p2不是常量(指針指向地址里面存的值可以改,指針指向地址不可改)
int * const p2 = &age;
// *p3是常量,p3是常量(指針指向地址里面存的值不可改,指針指向地址不可改)
const int * const p3 = &age;
// *p4是常量,p4是常量(跟上述一樣)
int const * const p4 = &age;

通過const修飾的結(jié)構(gòu)體對(duì)象,代碼如下:

struct Person {
   int age;
 };
Person per1 = { 10 };
Person per2 = { 20 };
//此時(shí)nPer指向不可更改,nPer指向?qū)ο罄锩娴膬?nèi)容可以更改
Person * const pPer = &per1;   
*pPer = per2; //正確
(*pPer).age = 30;//正確
pPer->age = 40;//正確
pPer = &per2; //錯(cuò)誤,不可改

//此時(shí)nPer1指向可以更改,但是nPer1指向?qū)ο蟛豢筛?const Person * pPer1 = &per1;
*pPer1 = per2; //錯(cuò)誤
(*pPer1).age = 30;//錯(cuò)誤
pPer1->age = 40;//錯(cuò)誤
pPer1 = &per2;//正確

常引用:被const修飾的引用不可更改,稱為常引用

int age = 10;
int number = 20;
//定義一個(gè)常應(yīng)用
const int &rage = age; 
rage = 20;//無法修改,報(bào)錯(cuò)
&rage = number;//無法修改,引用沒有這種寫法
  
//定義一個(gè)const指針
const int * const page = &age; 
*page = 20;//無法修改,報(bào)錯(cuò)
page = &number//無法修改,報(bào)錯(cuò)

最后補(bǔ)充一個(gè)常引用知識(shí)點(diǎn):當(dāng)常引用指向了不同類型的數(shù)據(jù)時(shí),會(huì)產(chǎn)生臨時(shí)變量,即引用指向的并不是初始化時(shí)的那個(gè)變量

int age = 10;
const int &rAge = age;
age = 30;
//age  is  30    
cout << "age is " << age << endl;
//rAge is 10
cout << "rAge is " << rAge << endl;

細(xì)心同學(xué)通過上述代碼發(fā)現(xiàn)了引用和指針達(dá)到的效果好像差不多,既然存在了指針,為什么C++還要用引用呢?這就涉及到引用的本質(zhì),它存在的價(jià)值是什么?我們后面再介紹,敬請(qǐng)期待。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 幾種語言的特性 匯編程序:將匯編語言源程序翻譯成目標(biāo)程序編譯程序:將高級(jí)語言源程序翻譯成目標(biāo)程序解釋程序:將高級(jí)語...
    囊螢映雪的螢閱讀 3,058評(píng)論 1 5
  • C++基礎(chǔ)2:類與對(duì)象 1. 認(rèn)識(shí)類與對(duì)象 什么是類(class)?類(class)是類型(type),是用戶自定...
    jdzhangxin閱讀 2,457評(píng)論 0 7
  • 重新系統(tǒng)學(xué)習(xí)下C++;但是還是少了好多知識(shí)點(diǎn);socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme閱讀 20,419評(píng)論 0 50
  • 這是C++類重新復(fù)習(xí)學(xué)習(xí)筆記的第 四 篇,同專題的其他文章可以移步:http://www.itdecent.cn...
    超級(jí)超級(jí)小天才閱讀 529評(píng)論 0 1
  • C++入門基礎(chǔ) namespace專題講座 namespace概念 所謂namespace,是指標(biāo)識(shí)符的各種可見范...
    蔡俊宇閱讀 870評(píng)論 0 2

友情鏈接更多精彩內(nèi)容