#C++Primer之 函數探幽算法
C++函數包括函數聲明和函數定義,函數聲明即函數原型,通常隱藏在include文件中。 ###爲何須要原型? 1.原型告訴編輯器,函數的參數,若是程序沒有提供正確的參數,讓編輯器可以捕獲這種錯誤。 2.函數執行完成後,將把返回值放置在指定的位置,編譯器根據函數原型的類型去檢索和解釋。 沒有以上信息,編譯器只能去猜想。 ###原型的功能數組
###指針和const const表示指向一個常量,該值不能被修改.編輯器
int n = 10; const int *p = &n;
p表示指向一個常量的指針,雖然不能夠經過p來需改n,可是能夠 經過n++來達到修改p指向的數據。 C++禁止將const的地址賦給非const地址,但容許將非const地址賦給const地址當且僅當只有一層間接關係時。 ###const的做用函數
char *build(char c, int n) { char *pstr = new char[n+1]; pstr[n] = '\0'; while(n>0) pstr[n--] = c; return pstr; }
變量pstr的做用域是函數內,所以函數執行結束時,pstr所使用的內存將被釋放,但因爲函數返回了pstr的值,程序仍然能夠在main()中的指針訪問新建的字符串。ui
###內聯函數 ####函數執行過程: 執行到函數調用指令時,程序將在函數調用後當即存儲該指令的內存地址,並將函數參數複製到對戰(爲此保留的內存塊),調到編輯函數七點的內存單元,執行函數代碼,而後跳回到地址被保存的指令處,來回跳躍並記錄跳躍位置意味着使用函數調用時須要必定的開銷。指針
void incline f();
內聯函數的編譯代碼和其餘程序代碼"內聯"了,即編譯器直接將相應的函數調用替換爲代碼,無需來回跳轉,使得運行速度比常規的函數快,代價是佔用更多的內存,因此通常要求內聯函數必須很短,被調用不少次。 ###將引用做爲參數傳遞給函數code
double refcube(double &ra); ... double x = 2.1; double z = refcube(x + 3.0);//error
上述代碼會編譯錯誤,由於x+3.0 不是變量。對象
double y = 3.2; double z = refcube(x+y);
這樣就不會報錯,這就涉及到了臨時變量、引用參數和const 若是實參和引用參數不匹配,C++將生成臨時變量,當且僅當參數爲const引用時,C++才容許這麼作。 若是引用參數是const,如下狀況將生成臨時變量:內存
void swap(int &a, int &b) {..}//swap a and b long a =3, b = 5; swap(a,b);
這裏類型不匹配,所以編譯器將建立兩個臨時的int變量,初始化爲3和5,而後交換臨時變量內容,而a和b不變. 因此const的做用還有另外一個做用就是使函數可以正確生成臨時變量 ###函數重載 函數重載的關鍵是函數的參數列表(也稱函數特徵標),即函數名相同,參數數目和類型以及排列順序也相同,則特徵值相同,參數變量名可有可無。作用域
double cube(double x); double cube(double &x);
此處不是函數重載,由於如代碼 cout<<cube(x);
x與double和double&都匹配,編譯器沒法肯定使用哪一個原型。爲避免混亂,編譯器檢查特徵表時,將類型引用和類型自己視爲同一個特徵標,此外匹配函數時並不區分const和非const。 是特徵標不是函數類型使得函數能夠對函數進行重載,一下爲互斥的:
long f(int a, int b); double f(int a, int b);
返回類型能夠不一樣,但特徵標必須不一樣。編譯器一般會根據參數列表對函數的民稱進行惟一標示,便於內部識別。 ###函數模板 函數模板是通用的函數描述,經過將類型做爲參數傳遞給模板,使編譯器生成可用具體的類型的函數。相似於:
template<class Any> void swap(Any &a, Any &b);
對於不一樣類型使用同一種算法,可以使用模板,有時須要像重載常規函數那樣去重載函數模板。