C primer 第8章節 函式探幽

2021-08-03 22:14:46 字數 4236 閱讀 5717

1. 內聯函式比一般的函式執行速度要稍快,但是代價是需要付出更多的記憶體。

如果程式在10個地方呼叫同乙個內聯函式,

那麼該程式將包含該程式的10個副本。

2. 使用內聯函式,可以有三種方法:

(1):在函式宣告的時候,加上關鍵字inline.

(2):在函式定義的時候,加上關鍵字inline.

(3):類中實現的函式,將自動轉化為inline.

但通常的做法是省略原則,將整個定義(函式頭和實現**)放在本應該提供原型的地方,即可以在標頭檔案中(非static型別的函式),

也可以是在cpp檔案中(static型別的函式)

3. 注意點:不是說我們加了關鍵字inline,編譯器就一定會將其原地展開,還得看編譯器具體實現的情況,一般較短的函式適合做inline。

4. 將int型別的資料傳遞給接受double型別引數的函式並沒有報警告,自動型別轉換,反之編譯器則會報告警告資訊.

從這個測試中可以得出乙個結論,函式傳參,小範圍可以賦值給大範圍,並且不會有警告,反之則可能有警告甚至錯誤

比如,non-const 型別可以傳遞給const型別的引數,反之則是不可以的.(

針對指標和引用)

5. 如果使用了巨集執行了類似函式的操作,應該考慮使用inline函式替換他們.

6. 定義引用變數的同時必須出現初始化,引用只是變數的乙個別名而已,更多的應用於引數傳參上邊.

7. 注意點:引用變數一旦與某個變數名繫結(即成為了這個變數名的乙個別名),那麼就不能將這個引用與其他變數繫結,簡單的說就是

引用變數只能被初始化的時候賦值,之後便不能修改引用變數的值,如果引用變數重新被變數賦值,那麼編譯器不會報錯,但是所有的

值都被修改了。相當於定義了乙個 int * const p; 這樣的指標,p初始化之後就不能修改p的值了.但*p卻還是可以被修改

8. 可以通過初始化的時候設定引用變數為哪個變數的別名,位址與哪個變數保持一致,但是不可以通過重新賦值引用變數來設定引用變數的

別名,如果重新賦值引用變數,含義是,修改了引用變數的記憶體的值,也就是引用變數的別名變數的值也是被修改了。

10.

getline(cin, inputstr),這裡getline是獲取輸入緩衝區的一行,包含空格等

cin >> inputstr; cin只獲取到輸入緩衝區中與inputstr型別移植的地方,後面的則省略了,保留在了緩衝區

11. 基類指標可以指向子類物件

12. ostream物件的格式化方法

***x = os.setf(ios_base::fixed); 該返回值為當前的格式化引數

os.precision(0); 設定要顯示的小數點位數

os.width(12); 設定顯示位寬

os.setf(***x); 恢復之前的格式化引數

13. 什麼時候使用指標,什麼時候使用引用?注意const的配合使用,盡可能加上const

(1) 對於內建型別,如果要修改內建型別的值,使用指標,否則使用按值傳遞

(2) 對於陣列,只能使用指標

(3) 對於結構體, 可以使用指標,可以使用引用

(4) 對於類物件,只用引用

14. 函式預設引數

(1).

只能是函式的原型宣告處需要指定預設值,函式定義與沒有預設引數時完全相同

(2). 對於帶引數列表的函式,必須從右向左向前預設值

(3). 實參傳遞時,也只能從左向右依次賦給形參,而不能跳過任何形參f(1, , 0),錯的

15. 函式過載和函式多型是一回事, 函式過載:引數不一樣(引數個數,引數型別, 引數順序)即可,返回值無要求,引數名稱也可不一樣

注意:型別引用和型別本身視為同種引數型別,如 double cube(double x)和double cube(double &x)

void print(int x, int y);

void print(double x, int y);

viod print(long x, int y);

如有上述三種函式過載情況,那麼當呼叫unsigned int x = 10; print(x, y)時會報錯,為因為, x為unsigned int,上述三種型別

都沒有unsigned int 型別的引數,而且都是可以將unsigned int 轉換為各自的型別,因此把編譯器弄糊塗了,所以報錯,但如果

上述只有乙個函式,那麼unsigned int 則可以強制 轉換而不報錯

注意2:void f1(char *x)

void f1(const char *x)

void f2(const char *x)

void f3(char *x)

如下:const char p1[20] = "flaksdjf;asd";

char p2[20] = "ssssssssssss";

f1(p1) 呼叫的是f1(const char *)

f1(p2) 呼叫的是f1(char *)

f2(p1) 呼叫的是f2(const char *x)

f2(p2) 呼叫的是f2(const char *x)

f3(p1) 沒有呼叫的函式

f3(p2) 呼叫的是f3(char *x)

16. 函式模板更為常見的做法是,將函式模板放到標頭檔案中,並在需要使用模板的檔案中包含標頭檔案

函式模板可以過載,特徵標不一樣即可,

模板函式中的引數並一定都是泛型,

17. 函式版本有如下幾種:

(1). 常用函式(非模板函式)

(2). 模板函式 templatevoid swap(t &a, t &b)

(3). 顯示具體化模板函式 template<> void swap(job &a, job &b) 或者省略(

注意顯示具體化的作用是:為某個特定的型別定義不同的實現)

(4). 每種函式對應的過載函式

18. 對於函式模板有如下使用方法:

隱式例項化(implicit instantiation):宣告函式模板,在呼叫函式時編譯器自動根據傳參型別生成相應的函式 templatevoid swap(t &a, t &b)

顯示例項化(explicit instantiation):宣告函式模板, 在呼叫函式時,指定模板需要生成的函式定義,使用:template void swap(int &a, int &b)(注意:顯示例項化的作用是在函式編譯器見就生成了函式)

顯示具體化(explicit specficatin):template <> void swap(int &a, int &b)

具體參見《c++ primer plus》p288

19.

對於非引用型別,同時定義函式 int f(int )和 int f(const int)是錯誤的,這兩者不能是過載函式,但對於引用和指標,卻可以過載的。

指向非const型別的引用和指標的變數,優先和非const型別的指標和引用結合.

如下:int a;

f(int a)

f(const int a)

f(int &a)

f(const int &a)

20. 非模板函式的有限級高於模板函式,但如果硬是想要選擇模板函式可以在函式名之後加上<>, cout << lesser<>(a, b) << endl; (

注意:lesser有非模板的過載函式,正常是選擇常規函式,但如果非要使用模板函式的話,可以在函式名之後加上<>)

模板函式顯示具體化,可以讓函式引數型別自動轉換,

double x = 10.23;

double y = 20.99;

cout << lesser(x, y) << endl; 這裡會將x,y 型別自動轉換為int型別,不過編譯器仍然是會發出警告的。

21. decltype 關鍵字可以獲取表示式,或者變數的型別,

decltype(x + y) cr; 定義了乙個(x + y)型別的變數c, decltype(func()),

也可以是函式,那麼型別為函式返回值的型別,這裡並不會真正去執行函式,而是獲取函式的返回值

auto 和 decltype結合使用

template

auto gt(t1 x, t2 y) -> decltype(x + y) //不將decltype(x + y)放置於函式的前面的原因是,此時x,y還沒有定義

22.隱式例項化:後面有程式用了,編譯器才會根據模板生成乙個例項函式,

顯式例項化:是無論是否有程式用,編譯器都會生成乙個例項函式,

顯示具體化:因為對於某些特殊型別,可能不適合模板實現,需要重新定義實現,此時就是使用顯示具體化的場景

c primer plus 第8章 函式探幽

c 擴 展 了 c 語 言 的 函 數 功 能 通 過 將 inline 關鍵 字 用 於 函 數 定 義 並 在 首 次 調 用 該 函 數 前 提 供 其 函 數 定 義 可 以 使 得c 艹 編 譯 器 將 該 函 數 視 為 內 聯 函 數 也 就 是 說 編 譯 器 不 是 讓 程 序 跳...

第8章節 程序控制

1.每乙個程序都有唯一的乙個非負整數程序id 2.核心態 程序呼叫了系統api 注意不是標準庫函式 正在執行核心 的狀態 使用者態 正在執行的是使用者編寫的 狀態 3.核心自舉 自舉是指上電自檢,即核心檢查硬體平台都擁有什麼硬體,為硬體載入驅動,最終載入根文 件系統並執行第乙個程序。程序id 1的程...

C primer第15章節詳解物件導向程式設計

include include sales item.h using namespace std class quote class bulk quote public quote int main double print total ostream os,const quote item,siz...