C++ 入門指南 4.01
單元 9 - 函數
函數 (function) 是一種功能性的模組,可以將程式 (program) 分割成小部分,藉由呼叫函數安排執行順序
定義函數需要指定函數的回傳值型態 (return type) 、函數名稱與小括弧中的參數列 (parameter list) ,後面的大括弧區域為函數工作的程式碼區域,如果有定義回傳值型態,大括弧中至少要有一個 return 陳述 (return statement) 。我們舉一例如下
int big(int a, int b) { // 判斷兩個參數的大小 if (a > b) { // a 大於 b ,回傳 a return a; } else { // a 小於 b ,回傳 b return b; } }
big() 函數回傳兩個參數 (parameter) 中的較大值,我們可以看到回傳值型態為 int ,函數名稱為 big ,參數數量則是依需求自己定義,這裡為兩個 a 與 b ,型態都是 int 。
這裡, a 與 b 都是屬於 big() 內的區域變數 (local variable) ,也就是效力僅限於 big() 後的大括弧中。
也可以不定義參數,這時參數列可宣告為 void 或留空白。
此例用了兩個 return ,有回傳值的函數至少要有一個 return , return 就是函數結束執行,將控制權交還原本呼叫函數的地方, return 後只能接運算式 (expression) 或單一數值。我們將 big() 寫成一個完整範例
#include <iostream> using namespace std; // 宣告 big() 的函數原型 int big(int, int); // main() 由作業系統呼叫,回傳整數給作業系統 int main(void) { cout << endl; // 呼叫 big() 並且印出回傳值 cout << big(22, 11) << " is bigger!"; cout << endl << endl; return 0; } // 函數 big() 的實際定義 int big(int a, int b) { // 判斷兩個參數的大小 if (a > b) { // a 大於 b ,回傳 a return a; } else { // a 小於 b ,回傳 b return b; } } /* 《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:big_demo.cxx 功能:示範定義函數 作者:張凱慶 */
此例在函數定義前先加入函數原型 (function prototype) 的宣告 (declaration) ,宣告亦為一行陳述,因此結尾要加分號
// 宣告 big() 的函數原型 int big(int, int);
宣告函數原型不需要加入參數的識別字,另外函數也可以不經宣告函數原型直接定義,此時函數定義就得放在 main() 之前。
我們在 main() 中呼叫 big() ,當 big() 執行完會在回到原本呼叫的地方,由於 big() 回傳一個整數,因此這裡就會直接印出 big() 的回傳值 (return value)
// 呼叫 big() 並且印出回傳值 cout << big(22, 11) << " is bigger!"; cout << endl << endl;
編譯後執行,結果如下
上例只有在 main() 中呼叫 big() 一次,如果有很多個數字需要比較,自然可以需要的次數呼叫。
函數的一個特點就是重複執行的程式碼用自行定義的識別字 (identifier) 代替,另舉一例如下
#include <iostream> using namespace std; // 宣告函數原型 void PrintInt(int); void PrintNewline(void); int main(void) { int i = 10; // 設定倒數的初值 PrintNewline(); // 印出空白一行 while (i > 0) { PrintInt(i); // 印出數字 i--; // 倒數 } PrintNewline(); // 印出空白一行 return 0; } // 印出參數 void PrintInt(int a) { cout << a << endl; } // 印出新行 void PrintNewline(void) { cout << endl; } /* 《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:print_demo.cxx 功能:示範定義函數 作者:張凱慶 */
這是我們之前寫過的倒數計時程式,只是將印出的工作定義給函數,這裡可以看到函數名稱可以使程式有清楚的語意
PrintNewline(); // 印出空白一行 while (i > 0) { PrintInt(i); // 印出數字 i--; // 倒數 } PrintNewline(); // 印出空白一行
編譯執行的結果是一樣的
函數是最基本也是最簡單的功能模組,可是 C++ 是物件導向程式語言 (object-oriented programming language) ,接下來,我們來看看怎麼樣來設計物件 (object) 吧!
中英文術語對照 | |
---|---|
宣告 | declaration |
運算式 | expression |
函數 | function |
函數原型 | function prototype |
識別字 | identifier |
區域變數 | local variable |
物件 | object |
物件導向程式語言 | object-oriented programming language |
參數 | parameter |
參數列 | parameter list |
程式 | program |
return 陳述 | return statement |
回傳值型態 | return type |
回傳值 | return value |
重點整理 |
---|
1. 函數為程式中功能性的模組,程式可藉由呼叫函數排列執行順序。 |
2. 定義函數須包括回傳值型態、函數名稱、參數列及函數的程式區塊。 |
3. 若不宣告函數原型,就得把函數定義放在 main() 之前。 |
4. 函數可以有回傳值,也可以沒有回傳值,有回傳值的函數利用 return 回傳數值。 |
5. 函數可以有參數,也可以沒有參數,沒有參數的函數在參數列宣告 void 或留空白。 |
6. 函數名稱為自行定義的識別字,可以有比較清楚的語意。 |
7. C++ 為物件導向程式語言,物件中除了有物件自己的函數,也可以有物件自己的變數。 |
問題與討論 |
---|
1. 參數跟回傳值在函數中的用途為何?為什麼可以有多個參數,卻只能有一個回傳值? |
2. 在函數中可以改變參數的值嗎? |
3. 什麼是區域變數?為什麼說參數是區域變數? |
練習 |
---|
1. 寫一個程式 exercise0901.cxx ,裡頭設計一個函數 sum() ,用以計算兩個整數的和。 參考程式碼 |
2. 承上題,另寫一個程式 exercise0902.cxx ,改成接受使用者輸入的版本。 參考程式碼 |
3. 寫一個程式 exercise0903.cxx ,裡頭設計一個函數 sum() ,只用一個整數參數 p ,結果回傳 1 到 p 之間所有正整數的和。 參考程式碼 |
4. 承上題,另寫一個程式 exercise0904.cxx ,改成接受使用者輸入的版本。 參考程式碼 |
5. 寫一個程式 exercise0905.cxx ,裡頭設計一個函數 factorial() ,用以計算階層值,並印出第十個階層值。 參考程式碼 |
6. 承上題,另寫一個程式 exercise0906.cxx ,改成用遞迴方式設計 factorial() 。 參考程式碼 |
7. 承上題,另寫一個程式 exercise0907.cxx ,改成接受使用者輸入的版本。 參考程式碼 |
8. 寫一個程式 exercise0908.cxx ,裡頭設計一個函數 fibonacci() ,用以計算費氏數列,並印出第二十個費氏數列的數字。 參考程式碼 |
9. 承上題,另寫一個程式 exercise0909.cxx ,改成用遞迴方式設計 fibonacci() ,並印出第二十個費氏數列的數字。 參考程式碼 |
10. 承上題,另寫一個程式 exercise0910.cxx ,改成接受使用者輸入的版本。 參考程式碼 |
相關教學影片