c++函數
在c++程式設計過程中,函數是經常用到的一個工具,它可以用來定義可重用的代碼,它可以使得主函數代碼看起來更加整潔,程式運作更加具有條理性,也有益于日後的修改與維護。
函數的基本概念:函數由傳回值類型、函數名、參數、參數清單、函數體、傳回值(有的函數可能沒有傳回值)組成。例如:
int pp(int n1,int n2)
{
//body
return n1;
}
這樣就定義了一個函數。總的而言,函數可以這樣表示:
returnValueType functionName (list of parameters)
{
//Fuction body
}
若要調用一個函數,可以這樣:
int z = pp(x,y);
接下來說明一些特殊的函數
1、無傳回值函數
void FunctionName (list of parameters)
{
//Function body
//這裡可以不用鍵入return 語句
}
因為無傳回值,是以不能對該函數使用指派符号調用
此外,也可以在函數中使用return語句提前結束函數,例如:
void print(doubel score)
{
if(score>100||score<0)
{
cout<<"Invalid";
return ;
}
else
{
cout<<"goodgoodgood";
.....
}
}
也可以在頭檔案cstdlib中調用exit(int)函數,通過傳遞任意一個整數來調用這個函數顯示程式中的錯誤。例如下面的例子,将在成績不合法(score>100 or score<0)時調用函數終結:
void print (double score)
{
if(score<0||score>100)
{
cout<<"Ivalid";
exid(1);
}
else
{
cout<<"lalala";
....
}
}
2、函數的重載
關鍵點:函數的重載使你可以用同樣的名稱命名函數,隻要函數的簽名不同
當使用函數的重載時,一般是讓需要處理不同資料類型,但是所要完成的任務相同的函數,取為相同的函數名。
什麼意思呢,例如這樣:
//接下來鍵入函數
int max(int num1,int num2)
{
if(num1>num2)
return num1;
else
return num2;
}
double max(double num1,double num2)
{
if(num1>num2)
return num1;
else
return num2;
}
這樣,同一個max函數,既可以對兩個int整型的數值進行處理,又可以對兩個double類型的浮點數進行處理,并且不用擔心沖突,因為編譯器會選擇資料類型最合适最比對的函數執行。
而且,注意:重載函數必須有不同的參數清單,不能依據不同的傳回類型重載函數。
此外,要保證不能模糊調用,模糊調用會導緻一個編譯錯誤,例如:
#include<iostream>
using namespace std;
int max(int n1,double n2)
{
if(n1>n2)
return n1;
else
return n2;
}
double max(doubel n1,int n2)
{
if(n1>n2)
return n1;
else
return n2
}
int main()
{
cout<<max(1,2)<<endl;
return 0;
}
這裡因為不管是int max的函數還是double max的函數,其形式參數的資料類型都與輸入的實際參數類型max(1,2)比對,且沒有一個更比對的,調用的對象很模糊,這樣就導緻了編譯錯誤。
當然如果輸入的是max(1,20.0)那麼将于第一種類型更加比對,這樣就不會導緻編譯錯誤。
注意:重載函數可以讓程式更清晰并且更具有可讀性。執行相同任務,但擁有不同類型的參數的函數應該使用相同的名字。
3、函數原型
在調用一個函數之前,必須在程式中聲明它,就比如說我們之前寫的程式,把所有需要用到的函數放在了主函數的前面,但是,這樣可能會導緻我們程式運作的主體不突出(主函數被埋沒在最底下了),是以,我們可以使用函數原型的方式。
一個函數原型,就是一個沒有函數體的一個單純的函數聲明,而将其函數體放在代碼的最後,例如:
#include<iostream>
using namespace std;
int max(int n1,int n2); //注意這個分号
int main()
{
cout<<max(1,2);
return 0;
}
int max(int n1,int n2)
{
if(n1>n2)
return n1;
else
return n2;
}
4、預設函數
關鍵點:可以為函數中的參數定義一個預設值(即預設值)
例如:
#include<iostream>
using namespace std;
void pp(int i=0)
{
int x=i*i;
cout<<x<<endl;
}
int main()
{
pp();
pp(4);
return 0;
}
程式的輸出如下:
0
16
這就是預設函數的妙用,當沒有給函數輸入一個值時,則使用預設值運作函數。
5、内聯函數
關鍵點:常使用内聯函數來提高函數性能
提到内聯函數,就不得不提到函數的一個缺點:
使用函數來實作程式,固然可以使得代碼更加整潔,更加具有可讀性,但是同時,再調用函數時有額外的運作時開銷(即将參數和CPU寄存器壓入調用棧,以及在函數切換控制所花費的時間)
這樣就有了内聯函數。
内聯函數不會被調用,實際上是編譯器把其代碼複制到了每一個調用點上。
為指定一個函數是内聯函數,在函數聲明之前加上關鍵字 inline 即可。例如:
#include<iostream>
using namespace std;
inline int max(int n1,int n2)
{
if(n1>n2)
return n1;
else
return n2;
}
int main()
{
int x,y,a;
cin>>x>>y;
a=max(x,y);
cout<<a;
return 0;
}
看起來似乎差不多,但這樣會在函數多次運作時大大提高程式運作的速度。
看起來inline似乎很好,但這樣僅僅是對于短函數而言的,因為如果函數較長,使用内聯函數将會急劇的增加代碼的長度,因為代碼會被編譯器複制到多個位置,故c++允許編譯器對過長的函數忽略inline關鍵字。
是以,inline隻是對編譯器提出了一個請求,是否執行由編譯器決定。