呼叫函式
定義函式的目的是為了呼叫此函式,以得到預期的結果。因此,應當熟練掌握呼叫函式的方法和有關概念
函式呼叫的形式
函式呼叫的一般形式為:
函式名(實參表列)
如果是呼叫無參函式,則“實參表列”可以沒有,但括號不能省略
如果實參表列包含多個實參,則各個引數之間用逗號隔開
按函式呼叫在程式中出現的形式和位置來分,可以有以下三種函式呼叫的方式:
- 函式呼叫語句
- 函式表示式
- 函式引數
函式呼叫語句
把函式呼叫單獨作為一個語句
此時不要求函式帶回值,只要求函式完成一定的操作
函式表示式
函式呼叫出現在另一個表示式中
此時要求函式帶回一個確定的值可以參加表示式的運算
函式引數
函式呼叫作為另一個函式呼叫時的實參
呼叫函式並不一定要求包括分號,只有作為函式呼叫語句才需要有分號。如果作為表示式或者函式引數,函式呼叫本身是不必有分號
函式呼叫時的資料傳遞
形式引數和實際引數
在呼叫有參函式時,主調函式和被調函式之間有資料傳遞關係。在定義函式時函式名後面括號中的變數名稱為“形式引數”(簡稱“形參”)或“虛擬引數”。在主調函式中呼叫一個函式時,函式名後面括號中的引數稱為“實際引數”(簡稱“實參”)。實際引數可以是常量、變數或表示式
實參和形參間的資料傳遞
在呼叫函式過程中,系統會把實參的值傳遞給被呼叫函式的形參。或者說,形參從實參得到一個值。該值在函式呼叫期間有效,可以參加該函式中的運算
在呼叫函式過程中發生的實參與形參間的資料傳遞,通常稱為“虛實結合”
實參可以是常量、變數或表示式;實參與形參的型別應相同或賦值相容
函式呼叫的過程
- 在定義函式中指定的形參,在未出現函式呼叫時,它們並不佔記憶體中的儲存單元。在發生函式呼叫時,函式的形參被臨時分配記憶體單元
- 將實參對應的值傳遞給形參
- 執行被調函式
- 透過
return
語句將函式值帶回到主調函式,如果函式不需要返回值,則不需要return
語句,這時函式應定義為void
型別 - 呼叫結束,形參單元被釋放。注意:實參單元仍保留並維持原值,沒有改變。如果在執行一個被調函式時,形參的值發生改變,不會改變主調函式的實參的值。這是因為實參和形參是兩個不同的儲存單元
實參向形參的資料傳遞是“值傳遞”,單向傳遞,只能由實參傳給形參,而不能由形參傳給實參
實參和形參在記憶體中內有不同的儲存單元,實參無法得到形參的值
函式的返回值
通常,希望透過函式呼叫使主調函式得到一個確定的值,這就是函式值(函式的返回值)
函式的返回值是透過函式中的 return
語句獲得的,return
語句將被呼叫函式中的一個確定值帶回一個函式值(供主調函式使用)被呼叫函式中必須包含一個 return
語句。如果不需要從被調函式帶回函式值可以不要 return
語句
一個函式中可以有一個以上的 return
語句,執行到哪一個 return
語句,哪一個 return
語句就起作用。return
語句後面的括號可以不要,return
後面的值可以是一個表示式
函式值的型別,既然函式有返回值,這個值當然應屬於某一個確定的型別,應當在定義函式時指定函式值的型別
在定義函式時指定的函式型別一般應該和 return
語句中的表示式型別一致
如果函式值的型別和 return
語句中表示式的值不一致,則以函式型別為準。對數值型資料,可以自動進行型別轉換,即函式型別決定返回值的型別
對於不帶回值的函式,應當用定義函式為“void
型別”(或稱“空型別”)這樣,系統就保證不使函式帶回任何值,即禁止在呼叫函式中使用被呼叫函式的返回值。此時在函式體中不得出現 return
語句
對被呼叫函式的宣告和函式原型
在一個函式中呼叫另一個函式(即被呼叫函式)需要具備如下條件:
- 首先被呼叫的函式必須是已經定義的函式(是庫函式或者使用者自己定義的函式)
- 如果使用庫函式,應該在本檔案開頭用
#include
指令將呼叫有關庫函式時所需用到的資訊“包含”到本檔案中來 - 如果使用使用者自己定義的函式,而該函式的位置在呼叫它的函式(即主調函式)的後面(在同一個檔案中),應該在主調函式中對被調函式作宣告。宣告的作用是把函式名、函式引數的個數和引數型別等資訊通知編譯系統,以便在遇到函式呼叫時,編譯系統能正確識別函式並檢查呼叫是否合法
函式的宣告和函式定義的第一行(函式首部)基本上是相同的,只差一個分號(函式宣告比翻書定義中的首行多一個分號)因此寫函式宣告時,可以簡單的照寫已定義的函式的首行,再加上一個分號,就成了函式的“宣告”函式的首行(即函式的首部)稱為函式原型
使用函式的首部作為函式宣告是為了便於對函式呼叫的合法性進行檢查。因為在函式的首部包含了檢查嗲用函式是否合法的基本資訊(包括了函式名、函式值型別、引數個數、引數型別和引數順序)
在檢查函式呼叫時要求函式名、函式型別、引數個數和引數順序必須與函式宣告保持一致,實參型別必須與函式宣告中的形參型別相同(或賦值相容,如實型資料可以傳遞給整型形參,按賦值規則進行型別轉換)否則就按出錯處理。這樣子就能保證函式的正確呼叫
使用函式原型作宣告是 C 的一個重要特點。用函式原型來宣告函式,能減少編寫程式中可能出現的錯誤。由於函式宣告和位置與函式呼叫語句的位置比較近,因此在寫程式時便於就近參照函式原型來書寫函式呼叫,不易出錯
實際上,在函式宣告中的形參名可以省寫,而只寫形參的型別
編譯系統之關心和檢查引數個數和引數型別,而不檢查引數名,因為在呼叫函式時只要求保證實參型別與形參型別一致而不必考慮形參名是什麼。因此在函式宣告中,形參名可寫可不寫,形參名是什麼都無所謂
函式原型的一般形式有兩種:
函式型別 函式名(引數型別1 引數名1, 引數型別2 引數名2, ... , 引數型別n 引數名n);
函式型別 函式名(引數型別1, 引數型別2, ... , 引數型別n);
對函式的“定義”和“宣告”不是同一回事。函式的定義是指對函式功能的確立,包括指定函式名、函式值型別以及形參及其型別以及函式體等,它是一個完整的、獨立的函式單位。而函式宣告的作用則是把函式的名字、函式型別以及形參的型別、個數和順序通知編譯系統,以便在呼叫該函式時系統按此進行對照檢查(如函式名是否正確,實參與形參型別和個數是否一致),它不包括函式體
如果已在檔案的開頭(在所有函式之前)已對本檔案中所呼叫的函式進行了宣告,則在各函式中不必對其所呼叫的函式再作宣告
由於在檔案的開頭(在函式的外部)已對要呼叫的函式進行了宣告(這些稱為“外部的宣告”)因此在程式編時,編譯系統已從外部宣告中知道了函式的有關資訊,所以不必再主調函式中再重複進行宣告。寫在所有函式前面的外部宣告在整個檔案範圍內有效