一個函數寫好后,若不通過函數調用,是發揮不了任何作用的。但在調用用戶自定義函數之前,還要做一件事--函數聲明。函數聲明的目的就是把函數的名字、函數類型以及參數的類型、個數和順序通知編譯系統,以便在調用該函數時系統按此進行對照檢查,從而可以正確編譯。
1.函數聲明:
在ANSI C新標準中,通常在調用函數之前在主調函數中聲明被調用函數,其一般格式如下:
函數類型 函數名(數據類型 參數名1,數據類型 參數名2...);
例如:
????????? int Put(int x,int y,int z,int color,char *p);?? //聲明一個整型函數
????????? char Name(void);?????????????????????????????????????? //聲明一個字符型函數
????????? void Student(int n,char *str);???????????????????? //聲明一個沒有返回值的函數
????????? float Selpi(void); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //聲明一個浮點型函數
說明:
函數聲明不是必須的,在一下3種情況下可以省去在主調函數中對被調函數的聲明:
(1)當被調用函數的函數定義出現在主調函數之前時。因為在調用之前,編譯系統已經知道了被調用函數的函數類型、參數個數、類型和順序。
(2)如果在所有函數定義之前,在函數外部(如頭文件或程序開始處)預先對各個函數進行了聲明,則在主調函數中可以省去對被掉調函數的說明。
(3)被調函數的函數類型為int型時。因為在調用函數之前,沒有對函數聲明,編譯系統自動會把第一次遇到的該函數形式(函數定義或函數調用)作為函數聲明,并將函數類型默認為int型。
2.函數調用的一般形式
函數聲明后,就可以調用函數了。函數調用的一般形式為:
函數名(實參列表);
說明:
(1)定義函數時函數名后面括號中的參數(變量)名稱為"形式參數"(簡稱"形參");相對應地把在主調函數中調用一個函數時函數名后面括號中的參數(可以是一個表達式)稱為"實際參數"(簡稱"實參")。
(2)實參必須在類型上按順序與形參一一對應和匹配。如果類型不匹配,C編譯程序將按賦值兼容的規則進行轉換。如果實參和形參的類型賦值時不兼容,通常并不給出出錯信息,并且程序仍然繼續執行,只是得不到正確的結果。
(3)如果實參表中包括多個參數表達式,對實參的求值順序則隨系統而異。有的系統按自左向右的順序求實參的值,有的系統則相反,這一點讀者尤其要注意。
(4)調用函數時,函數名稱必須與具有該功能的自定義函數名稱完全一致。
在C語言中,可以用以下幾種方式調用函數:
(1)函數表達式。函數作為表達式的一項出現在表達式中,以函數返回值參與表達式的運算。這種方式要求函數是有返回值的。
(2)函數語句。C語言中的函數可以只進行某些操作而不返回函數值,這時的函數調用可以作為一條獨立的語句。
(3)函數實參。函數作為另一個函數調用的實際參數出現。這種情況是把該函數的返回值作為實際參數進行傳送,因此要求該函數必須是有返回值的。
函數的參數
在主調函數和被調函數之間的數據傳遞是通過函數的參數進行的,實際上這也是數據共享的一種形式。形參的作用就是實行主調函數與被調函數之間的數據傳遞,通常將函數所處理的數據、影響函數的因素或者函數處理的結果作為形參。沒有形參的函數在形參表的位置應該寫void。
C語言規定,實參變量對形參變量的數據傳遞是單向傳遞,即只由實參傳給形參,而不能由形參傳回給實參。
函數返回值
函數的返回值是通過函數中的return語句獲得的。return語句將被調函數中的一個確定值帶回主調函數中去。return語句的一般格式是:
return(函數表達式);
(1)return語句的功能:返回主調函數,并將“返回表達式”的值帶給主調函數。
(2)函數的返回值可以有一個以上的return,哪一個return語句起作用要看使用的具體環境。例如:
int MIn(int num1,int num2)
{
??????? if(num1>num2)
??????? return (num2);? ????
??????? else
???????? return (num1);
}
若num1>num2的條件為真,執行return(num2),這時函數不再往下執行,而是返回到主調函數中執行下面的語句,否則函數執行return(num1)語句并返回。
(3)函數的返回值是確定的,這里包含兩層意思,一是函數值的類型確定,二是函數的返回值確定,即在return語句中的表達式的值必須確定。
(4)調用函數中無return語句,并不是不返回一個值,而是一個不確定的值。為了明確表示不返回值可以用“void”定義成“無(空)類型”。為了使程序具有良好的可讀性并減少出錯,凡不要求返回值的函數都應定義為空類型,而不是使用系統的默認處理。
(5)在定義函數時,對函數類型的說明應與return語句中返回值表達式的類型一致。如果不一致,則以函數類型為準。系統將默認函數類型按int來處理。
函數調用的執行過程
一個C語言程序經過編譯鏈接以后生成可執行代碼,形成后綴為exe的文件,存放在外存儲器中。當程序被啟動時,首先從外存將程序代碼裝載到內存的代碼區,然后從入口地址(main()函數的起始處)開始執行。程序執行過程中如果遇到了其它函數的調用,則暫停當前函數的執行,保存下一條指令的地址(即返回地址,作為從被調用函數返回后繼續執行的入口點),并保存現場(如中間變量等是現場內容),然后轉到被調用函數的入口地址,執行被調函數。當遇到return語句或者被調函數結束時,則恢復先前保存的現場,并從先前保存的返回地址開始繼續執行。
?