day_02_布爾、函數重載、內存分配、引用

六、C++布爾類型

  1、bool類型是C++中基本數據類型,專門表示邏輯值;
    true表示邏輯真,false表示邏輯假
  2、bool類型在內存中佔一個的內存:1表示true,0表示false
  3、bool類型的變量可以接收任意類型的表達式的值,其值非0則爲true,0爲false

七、操作符別名(瞭解)

&&  ==>  and
||  ==>  or
{   ==>  <%
}   ==>  %>
...

八、C++的函數(重點)

1、函數重載

eg:圖形庫的一些繪圖函數

void draw(int x, int y, double r){}
void draw(int x, int y, int w, int h){}

1)定義

在相同的作用域中,定義同名的函數,但是它們的參數不同,這樣的函數構成重載關係。

注意:
  函數的重載和返回的類型無關;通過函數指針調用重載關係的函數,由函數指針類型決定調用哪個版本,而不再由實參類型決定調用哪個版本。

2)函數重載匹配

調用重載關係的函數時,編譯器將根據實參和形參的匹配程序,自動選擇最優的匹配版本。

g++ v6.3.0:
  完全匹配 > 常量轉換 > 升級轉換 > 降級轉換 > 省略號匹配

3)函數重載的原理

C++編譯器是通過對函數進行換名,將參數類型信息整合到新的名字中,解決函數重載與名字衝突的矛盾。

筆試題:extern "C"聲明的作用???
答案:要求C++編譯器不對函數做換名,便於C程序調用該函數。(無法重載)
語法:

extern "C" void func();
extern "C" {
    void func1();
    void func2();
    ...
}
  • 擴展:函數的重入、重載、重寫區別

2、函數的缺省參數(默認實參)

1)可以爲函數的參數執行缺省值,調用該函數時,如果不給實參,就取缺省值作爲相應的形參的值。

eg:

void mysend(int sockfd, void* buf, int size, int flag=0);

2)如果函數的聲明和定義分開,缺省參數寫在聲明部分,而定義部分不寫。
3)缺省參數必須靠右,如果一個參數有缺省值,那麼這個參數的右側所有參數都必須帶有缺省值。

3、函數的啞元參數(瞭解)

1)定義:只有類型而沒有形參變量名的形參稱爲啞元參數;
eg:

void func(int/* 啞元 */){}
int main(){
    func(10);
}

2)使用場景
  –>爲了兼容舊的代碼
eg:算法函數

void math_func(int a, int = 0){..}
//使用者:
int main(){
    math_func(10, 20);
    ...
    math_func(30, 40);
}
//升級算法函數:
void math_func(int a){..}

  –>操作符重載中,區分前後++/--(後面講)

4、內聯函數(inline)

筆試題:inline關鍵字的作用?
1)定義

使用inline關鍵字修飾的函數,表示這個函數就是內聯函數,編譯器會對內聯函數做內聯優化,避免函數調用的開銷。

inline 返回類型 函數名(形參表){} //內聯函數

2)適用場景

a. 多次調用小而簡單的函數適合內聯;
b. 調用次數極少或者大而複雜的函數不適合內聯;
c. 遞歸函數不適合內聯;

注意:
  內聯只是一種優化的建議而不是強制要求,能否內聯優化主要取決於編譯器,有些函數不加inline關鍵字也會默認處理爲內聯優化,有些函數即使加了inline也會被編譯器忽略。


//循環一:
for(int i = 0;i < 1000;i++)
    for(int j=0;j < 100000;j++)
        dosomething();
----------------------------
//循環二:
for(int j=0;j < 100000;j++)
    for(int i = 0;i < 1000;i++)
        dosomething();
//循環一的效果好,循環跳入跳出的次數較少。

九、C++的動態內存分配

筆試題: C++中的new/delete,和C中malloc()/free()區別

1、回顧C語言中動態內存分配

1)分配:malloc()/calloc()/realloc()
2)釋放:free()
3)錯誤處理:返回值

2、C++使用new/delete運算符分配內存

1)分配:new new[]
2)釋放:delete delete[]
3)錯誤處理:異常(後面講)
//int* p = (int *)malloc(sizeof(int));
int* p = new int;
*p = 100;
//free(p);
delete p;
----------------------------------
//int* p = (int *)malloc(sizeof(int));
//*p = 0;
int* p = new int(0);  //分配內存同時初始化
*p = 100;
//free(p)
delete p;
----------------------------------
//int* pa = (int*)malloc(sizeof(int)*10);
int* pa = new int[10];
//free(pa);
delete[] pa;

十、C++引用(reference)(重難點)

1、定義:

1)引用就是某個變量的別名,對引用的操作與對該變量的操作相同
2)語法:
    類型 & 引用名(別名) = 變量;
注:引用在定義時要綁定一個變量,初始化以後不能修改。
注:引用的類型與綁定類型要一致。

eg:

int a = 100;
int & b = a;        // b就是a的別名
b++;                // 等價於a++;
cout << a << endl;  // 101

int c = 200;
b = c;              // 將c的值賦值給b,等價於a = c;
cout << a << endl;  // 200

2、常引用

1)定義引用時加const修飾,即爲常引用,不能通過常引用修改引用的目標。
2)語法:
    const 類型& 引用名(別名) = 變量/右值;(右值只能放在等號右邊)
    類型 const& 引用名(別名) = 變量/右值;

eg:

int a = 0;
const int& b = a;   // b就是a的常引用
b = 10;             // error

注:
  普通的引用只能引用左值,而常引用既可以引用左值也可以引用右值,所以也可以把常引用稱爲萬能引用。

eg:

int& r = 100;       // error
const int& r = 100; // ok

關於左值和右值;

1)左值:可以放在賦值運算符的左側

int a = 10;      //不是賦值運算,是初始化
a = 20;          //賦值

  –>普通的變量都是左值;
  –>前++/–表達式結果是左值;

int num = 0;
++num = 10;      //ok
++++++num;       //ok

  –>賦值表達式結果是左值;

int a = 0;
int b = 10;
(a = b) = 20;
cout << a << ',' << b << endl; // 20,10

2)右值:只能放在賦值運算符右側

  –>字面值常量都是右值
  –>大多數表達式結果都是右值

eg:後++/–算符運算 邏輯運算 …

int num = 0;
num++ = 10; //error
發佈了50 篇原創文章 · 獲贊 48 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章