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...