http://c.biancheng.net/cpp/biancheng/view/31.html
在上一節,我們已經學會了如何閱讀函數原型和如何調用一個函數。然而,僅靠系統給出的標准庫函數是不夠用的。我們有時候要根據我們的實際要求,寫出一個合適自己使用的函數。
那么,我們如何來自己動手編寫一個函數呢?
首先,我們要告訴電腦,我們自己編寫了一個函數,即這個函數是存在的,這叫作函數的聲明(Declaration)。其次,我們要告訴電腦這個函數是怎么運作的,這叫作函數的定義(Definition)。顯然,函數的聲明和函數的定義是兩個不同的概念。聲明表示該函數存在,而定義則是表示該函數怎么去運行。
我們平時做事都是要有先后順序的,如果把次序顛倒了可能會惹些麻煩出來。編寫函數的時候也一樣。我們必須在調用一個函數之前就告訴電腦這個函數已經存在了,否則就成了“馬后炮”。所以,我們一般把函數的聲明放在主函數前面。
函數的聲明
在C++中,函數原型就是函數的聲明。所以,函數原型除了向用戶說明如何使用一個函數以外,還告訴電腦存在這樣一個可以使用的函數。
我們已經介紹了函數原型的結構,只不過“產生結果類型”這個名稱是為了方便理解而起的。它應該稱為“返回值類型”,用任意一種數據類型來表示,比如int或者char等等,當然還包括空類型void。多個參數則構成了“參數表”,表示運行這個函數需要哪些數據。於是,函數原型的結構就是:
返回值類型函數名(參數表);
函數聲明同變量的聲明一樣,是一句語句。所以在語句結束要加上分號。函數名、參數名的規則和注意事項同變量名一樣。
關於“返回”的概念稍后再作介紹,我們先來說說參數表。我們知道,在聲明函數的時候,會寫一些參數,而在調用函數的時候需要一一對應地填入這些參數。雖然它們都叫參數,但在不同的情況下,它們的含義是不同的。在聲明一個函數的時候,參數是沒有實際值的,只是起到一個占位的作用,所以稱為形式參數,簡稱“形參”;在調用一個函數的時候,參數必須有一個確定的值,是真正能夠對結果起作用的因素,所以稱為實際參數,簡稱“實參”。我們拿數學中的函數作為例子,g(x,y)=x/4+y中的x和y就是形式參數,而g(4,1)=4/4+1=2中的4和1就是實際參數;如果令a=4、b=1,那么g(a,b)中的a和b也是實際參數。
函數的定義
說完了函數的聲明,我們來說函數的定義。其實函數的定義對大家來說是比較熟悉的。因為我們之前所寫的程序都是對主函數的定義。函數定義的格式為:
沒有分號結尾的函數原型
{
語句塊;
}
我們把函數定義中沒有分號結尾的函數原型稱為函數頭,把之后的語句塊稱為函數體。任何一個函數的定義不能出現在另一個函數體內。但函數體內可以調用任何一個函數,包括其本身。
下面我們先來看一個例子,你就會對函數定義有些了解了。(程序6.2.1)
運行結果:
5
程序在運行的時候從main函數開始,遇到調用一個用戶定義的函數max,則去查找這個max函數的定義,然后運行max函數。運行完了以后,回到調用max函數的地方,繼續后面的語句,直到程序結束。所以整個程序的運行過程如箭頭所示。
不要使用相同的變量和參數
如果在一個班級里有兩個同名同姓的同學,那么老師上課點名將是件麻煩事。因為大家都搞不清到底是在叫誰。可是,如果兩個不同的班級有兩個同名同姓的同學,就不會發生這種尷尬,因為老師在不同的教室點相同的名字,會有反應的只有一個同學。
我們把這個問題套用到函數上來。如果在同一個函數有兩個名字相同的變量,那么電腦將無法分清到底要使用哪個變量,導致錯誤發生。而在不同的函數中,即使有相同名稱的變量,由於在某一個函數中該變量的名稱是唯一的,電腦也能方便的識別要使用哪個變量。因此,我們得到這樣一個結論:一般情況下,在同一個函數中,不能有名稱相同的變量或參數;在兩個不同的函數中,可以有名稱相同的變量或參數。
下面就讓我們來看一個實例:(程序6.2.2)
#include "iostream.h"
int max(int a,int b,int c);//求三個整數的最大者
int min(int a,int b,int c);//求三個整數的最小者
void output(int a);//輸出功能
int main()
{
int a=3,b=4,c=2;
output(max(a,b,c));//把max函數的返回值作為output函數的實參
output(min(a,b,c));
return 0;
}
int max(int a,int b,int c)//不在同一個函數中,參數名重復沒關系
{
if (a>=b && a>=c) return a;
if (b>=a && b>=c) return b;
return c;//一旦執行了前面的return,這句就不會被執行到
}
int min(int a,int b,int c)
{
if (a<=b && a<=c) return a;
if (b<=a && b<=c) return b;
return c;
}
void output(int a)
{
cout <<a <<endl;
return;//返回空類型
}
運行結果:
4
2
要注意,一旦函數運行結束,那么該函數中聲明的參數和變量都將消失。就像下課了,同學們都回家了,老師叫誰都是叫不應的。