六、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