
函數 (function) 是一種功能性的模組,可以將程式 (program) 分割成小部分,藉由呼叫函數安排執行順序

定義函數需要指定函數的回傳值型態 (return type) 、函數名稱與小括弧中的參數列 (parameter list) ,後面的大括弧區域為函數工作的程式碼區域,如果有定義回傳值型態,大括弧中至少要有一個 return 陳述 (statement) 。我們舉一例如下
| 001 | int big(int a, int b) { |
| 002 | // 判斷兩個參數的大小 |
| 003 | if (a > b) { |
| 004 | // a 大於 b ,回傳 a |
| 005 | return a; |
| 006 | } |
| 007 | else { |
| 008 | // a 小於 b ,回傳 b |
| 009 | return b; |
| 010 | } |
| 011 | } |
big() 函數回傳兩個參數 (parameter) 中的較大值,我們可以看到回傳值型態為 int ,函數名稱為 big ,參數數量則是依需求自己定義,這裡為兩個 a 與 b ,型態都是 int 。
這裡, a 與 b 都是屬於 big() 內的區域變數 (local variable) ,也就是效力僅限於 big() 後的大括弧中。
也可以不定義參數,這時參數列可宣告為 void 或留空白。
此例用了兩個 return ,有回傳值的函數至少要有一個 return , return 就是函數結束執行,將控制權交還原本呼叫函數的地方, return 後只能接運算式 (expression) 或單一數值。我們將 big() 寫成一個完整範例
| 001 | #include <iostream> |
| 002 | |
| 003 | using namespace std; |
| 004 | |
| 005 | // 宣告 big() 的函數原型 |
| 006 | int big(int, int); |
| 007 | |
| 008 | // main() 由作業系統呼叫,回傳整數給作業系統 |
| 009 | int main(void) { |
| 010 | cout << endl; |
| 011 | // 呼叫 big() 並且印出回傳值 |
| 012 | cout << big(22, 11) << " is bigger!"; |
| 013 | cout << endl << endl; |
| 014 | |
| 015 | return 0; |
| 016 | } |
| 017 | |
| 018 | // 函數 big() 的實際定義 |
| 019 | int big(int a, int b) { |
| 020 | // 判斷兩個參數的大小 |
| 021 | if (a > b) { |
| 022 | // a 大於 b ,回傳 a |
| 023 | return a; |
| 024 | } |
| 025 | else { |
| 026 | // a 小於 b ,回傳 b |
| 027 | return b; |
| 028 | } |
| 029 | } |
| 030 | |
| 031 | /* 檔名: big_demo.cpp |
| 032 | 作者: Kaiching Chang |
| 033 | 時間: 2014-5 */ |
此例在函數定義前先加入函數原型 (function prototype) 的宣告 (declaration) ,宣告亦為一行陳述,因此結尾要加分號
| 005 | // 宣告 big() 的函數原型 |
| 006 | int big(int, int); |
宣告函數原型不需要加入參數的識別字,另外函數也可以不經宣告函數原型直接定義,此時函數定義就得放在 main() 之前。
我們在 main() 中呼叫 big() ,當 big() 執行完會在回到原本呼叫的地方,由於 big() 回傳一個整數,因此這裡就會直接印出 big() 的回傳值
| 011 | // 呼叫 big() 並且印出回傳值 |
| 012 | cout << big(22, 11) << " is bigger!" << endl; |
編譯後執行,結果如下

上例只有在 main() 中呼叫 big() 一次,如果有很多個數字需要比較,自然可以需要的次數呼叫。
函數的一個特點就是重複執行的程式碼用自行定義的識別字 (identifier) 代替,另舉一例如下
| 001 | #include <iostream> |
| 002 | |
| 003 | using namespace std; |
| 004 | |
| 005 | // 宣告函數原型 |
| 006 | void PrintInt(int); |
| 007 | void PrintNewline(void); |
| 008 | |
| 009 | int main(void) { |
| 010 | int i = 10; // 設定倒數的初值 |
| 011 | |
| 012 | PrintNewline(); // 印出空白一行 |
| 013 | while (i > 0) { |
| 014 | PrintInt(i); // 印出數字 |
| 015 | i--; // 倒數 |
| 016 | } |
| 017 | PrintNewline(); // 印出空白一行 |
| 018 | |
| 019 | return 0; |
| 020 | } |
| 021 | |
| 022 | // 印出參數 |
| 023 | void PrintInt(int a) { |
| 024 | cout << a << endl; |
| 025 | } |
| 026 | |
| 027 | // 印出新行 |
| 028 | void PrintNewline(void) { |
| 029 | cout << endl; |
| 030 | } |
| 031 | |
| 032 | /* 檔名: print_demo.cpp |
| 033 | 作者: Kaiching Chang |
| 034 | 時間: 2014-5 */ |
這是我們之前寫過的倒數計時程式,只是將印出的工作定義給函數,這裡可以看到函數名稱可以使程式有清楚的語意
| 012 | PrintNewline(); // 印出空白一行 |
| 013 | while (i > 0) { |
| 014 | PrintInt(i); // 印出數字 |
| 015 | i--; // 倒數 |
| 016 | } |
| 017 | PrintNewline(); // 印出空白一行 |
編譯執行的結果是一樣的

函數是最基本也是最簡單的功能模組,可是 C++ 是物件導向程式語言 (object-oriented programming language) ,物件中除了可以有函數也可以有變數,接下來,我們來看看怎麼樣來設計物件吧!
中英文術語對照
| 函數 | function |
| 程式 | program |
| 回傳值型態 | return type |
| 參數列 | parameter list |
| 陳述 | statement |
| 參數 | parameter |
| 區域變數 | local variable |
| 運算式 | expression |
| 函數原型 | function prototype |
| 宣告 | declaration |
| 識別字 | identifier |
| 物件導向程式語言 | object-oriented programming language |
重點整理
- 函數為程式中功能性的模組,程式可藉由呼叫函數排列執行順序。
- 定義函數須包括回傳值型態、函數名稱、參數列及函數的程式區塊。
- 若不宣告函數原型,就得把函數定義放在 main() 之前。
- 函數可以有回傳值,也可以沒有回傳值,有回傳值的函數利用 return 回傳數值。
- 函數可以有參數,也可以沒有參數,沒有參數的函數在參數列宣告 void 或留空白。
- 函數名稱為自行定義的識別字,可以有比較清楚的語意。
- C++ 為物件導向程式語言,物件中除了有物件自己的函數,也可以有物件自己的變數。
問題與討論
- 參數跟回傳值在函數中的用途為何?為什麼可以有多個參數,卻只能有一個回傳值?
- 在函數中可以改變參數的值嗎?
- 什麼是區域變數?為什麼說參數是區域變數?
練習
- 寫一個程式 exercise0901.cpp ,裡頭設計一個函數 sum() ,用以計算兩個整數的和。
- 承上題,另寫一個程式 exercise0902.cpp ,改成接受使用者輸入的版本。
- 寫一個程式 exercise0903.cpp ,裡頭設計一個函數 sum() ,只用一個整數參數 p ,結果回傳 1 到 p 之間所有正整數的和。
- 承上題,另寫一個程式 exercise0904.cpp ,改成接受使用者輸入的版本。
- 寫一個程式 exercise0905.cpp ,裡頭設計一個函數 factorial() ,用以計算階層值。
- 承上題,另寫一個程式 exercise0906.cpp ,改成用遞迴方式設計 factorial() 。
- 承上題,另寫一個程式 exercise0907.cpp ,改成接受使用者輸入的版本。
- 寫一個程式 exercise0908.cpp ,裡頭設計一個函數 fibonacci() ,用以計算費氏數列。
- 承上題,另寫一個程式 exercise0909.cpp ,改成用遞迴方式設計 fibonacci() 。
- 承上題,另寫一個程式 exercise0910.cpp ,改成接受使用者輸入的版本。
the end
沒有留言:
張貼留言