c primer plus筆記(5)函式基礎

2021-08-21 01:35:58 字數 4430 閱讀 9402

return_typename function_name(typename parameter_name,...)   //函式原型(函式頭)

①形參(parameter)與傳值呼叫:

1>形參:

函式原型處的形參,其名稱僅相當於佔位符。

所以單獨宣告函式原型的時候也可將變數名省略。

return_typename function_name(typename ,...)
2>傳值呼叫:

僅將實參的值(的拷貝)傳遞給形參,而非實參位址處的實參本身。

因此傳值呼叫關心的是使用該值得到的結果而不是處理和改變,其不影響原實參在記憶體中的值。

#includevoid swap(int* const, int* const); //指標作為形參,相應的函式原型也應修改

int main()

void swap(int* const a, int* const b)

#include "stdafx.h"

#includevoid swap(int& const, int& const); //引用作為形參,相應的函式原型也應修改

int main()

void swap(int& const a, int& const b)

以上兩種方法執行結果相同:

//為儘量減少不必要的錯誤,形參(尤其是指標或引用)的修改許可權應盡可能的低,使用const嚴格限定其行為

//由於陣列名可以近似的看做const指標,(或者說陣列本來就是通過指向記憶體塊的指標來呼叫的)所以陣列做形參的任何一種寫法都不能實現陣列的傳值呼叫。換句話說,當陣列作為形參時,使用的一定是其本身而不是其拷貝。

以c-style string為例:

void array_funct(const char);

void array_funct(const char*);

兩種寫法並沒有什麼區別。

3>引數傳遞方式的選擇:

(1)使用傳遞的值而不修改,且資料結構本身很小----傳值;

(2)陣列或內建資料型別----指標;(不修改則const限定)

(3)其餘情況一般全部使用引用;(不修改則const限定)

4>引數的預設值:

int function(const char*,int n=1);    //當n沒有被提供值,則使用預設值1
//預設引數必須出現在形參列表的最右邊。

//預設引數只寫在函式原型中,而函式定義部分不寫。

②返回值(return value)與引用:

事實上,通常情況下呼叫函式得到返回值都是其原本值的拷貝,而不是其本身;

而返回引用型別則使得返回原位址處的值。

int& funct();
所以應積極使用引用作為返回值型別。

1>返回引用型別的原因:①省去了拷貝的開銷,效率更高,尤其對於越是大的資料結構。

②左值用法。

//左值(l-value):位址(記憶體塊),如&和*型別;

//右值(r-value):(無址)資料,如字面值和表示式;

int& funct(a)=b;   //將b的值寫入funct(a)的返回值位址處
2>返回引用型別的注意事項:①由於允許左值用法,可能導致一些不易察覺的書寫錯誤,為減少這種錯誤應盡可能使用const限                                              定引用返回值。

②返回的位址應當有效,在函式體中定義的臨時變數,不能作為引用型別返回。

int& funct(int& ft)

//但如果建立的臨時變數是使用new建立在heap區,那麼其引用就可以作為引用型別返回;

被引用的引數可以作為引用型別返回:

int& funct(int& ft)

宣告方法:

int funct(int*);      //宣告乙個函式

int (*p_funct)(int*); //宣告乙個和該函式特徵標相同的指標

pf = funct; //將指標指向該函式

//pf = funct; 該句也說明函式名本身就是函式的入口位址,也就不必&funct。

//在函式指標被使用的情況下,函式的形式可能變得非常複雜,呼叫時書寫冗長,此時可使用自動型別推斷auto或typedef減少書寫量:

const double* funct(const double*,int);           //函式宣告

const double* (*p_funct)(const double*,int); //指標宣告

typedef const double* (*temp)(const double*,int); //將temp作為函式指標const double* (*)(const double*,int)型別的別名

temp funct1=funct; //將函式指標指向函式

常規函式在每次呼叫時通過函式名尋找跳轉至函式stack區,並記錄下執行完應該返回的位址,呼叫結束後返回主程式繼續執行。

內聯(inline)與巨集定義有一定相似性,在編譯時使用預設的固有函式**直接展開在每乙個呼叫處,其行為更接近符號。

inline void funct();   //定義乙個內聯函式
//內聯函式只在標頭定義,不將宣告與原型分開,行數不宜過多(一般都寫在同一行);

//遞迴函式不能內聯;

//內聯函式不能進行異常規範宣告;

//內聯函式節省了呼叫函式時的跳轉開銷,但代價是會使程式體積增大,因此不宜用於函式體複雜的(如含有switch、while)函式。

過載(overloading)函式呼叫時以引數列表(特徵標)來區分應匹配的原型:

函式過載適合於多個同名函式基本執行同樣的任務,但引數型別及所需實現不同的場合。

void funct(int,char*);

void funct(int,int,char*); //引數數目不同

void funct(char,char*); //引數型別不同

①過載的注意事項:

1>返回值不能作為過載依據:

void funct(int,char*);

int* funct(int,char*); //衝突的宣告

2>以const限定為依據的過載只對指標(*)和引用(&)型別引數起作用:

指標(*)型別同,不再列舉。

3>當沒有任何原型與呼叫處的引數匹配時,將嘗試執行轉換:

void funct(int,const char*);

void funct(int,int,const char*);

int main()

...

//當存在多個轉換途徑時,拒絕呼叫該函式:

void funct(int,const char*);

void funct(double,const char*);

void funct(int,int,const char*);

int main()

...

學習筆記 C primer Plus 第5章

1.typedef機制 使用typedef為現有型別建立別名,例如,typedef double real real dead 這兩行的含義表示把real建立為double型別的變數。2.遞增運算 i 和 i 前者 字尾表示使用i的值之後,遞增i。後者 字首表示先遞增i,然後使用i的值。3.沒乙個表...

c primer plus學習筆記

1.變數名命名規則 重要的 1 有含義 2 只能用字母字元 數字和下劃線 3 第乙個字元不能是數字 4 區分大小寫 5 不能用c 關鍵字 2.整型 1 無符合型別不能表負值 2 char short 16 int short long 32,int 和longlong 64,long c 11 寬度...

C PrimerPlus學習筆記

if語句中判斷恒等,將常量放前,防止由於 寫成 造成的難以查詢的bug。if 0 count 若寫成 0 count 會報錯,count 0 則不會命名空間 using namespace std cout one cout two std cout one std cout two using s...