函數 (function) 是一種功能性的模組,可以將程式 (program) 分割成小部分,藉由呼叫函數安排執行順序
定義函數需要指定函數的回傳值型態 (return type) 、函數名稱與小括弧中的參數列 (parameter list) ,後面的大括弧區域為函數工作的程式碼區域,如果有定義回傳值型態,大括弧中至少要有一個 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.cpp
功能:示範定義函數
作者:張凱慶 */
此例在函數定義前先加入函數原型 (function prototype) 的宣告 (declaration) ,宣告亦為一行陳述,因此結尾要加分號
// 宣告 big() 的函數原型
int big(int, int);
宣告函數原型不需要加入參數的識別字,另外函數也可以不經宣告函數原型直接定義,此時函數定義就得放在 main() 之前。
我們在 main() 中呼叫 big() ,當 big() 執行完會在回到原本呼叫的地方,由於 big() 回傳一個整數,因此這裡就會直接印出 big() 的回傳值
// 呼叫 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.cpp
功能:示範定義函數
作者:張凱慶 */
這是我們之前寫過的倒數計時程式,只是將印出的工作定義給函數,這裡可以看到函數名稱可以使程式有清楚的語意
PrintNewline(); // 印出空白一行
while (i > 0) {
PrintInt(i); // 印出數字
i--; // 倒數
}
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 |
重點整理 |
---|
1. 函數為程式中功能性的模組,程式可藉由呼叫函數排列執行順序。 |
2. 定義函數須包括回傳值型態、函數名稱、參數列及函數的程式區塊。 |
3. 若不宣告函數原型,就得把函數定義放在 main() 之前。 |
4. 函數可以有回傳值,也可以沒有回傳值,有回傳值的函數利用 return 回傳數值。 |
5. 函數可以有參數,也可以沒有參數,沒有參數的函數在參數列宣告 void 或留空白。 |
6. 函數名稱為自行定義的識別字,可以有比較清楚的語意。 |
7. C++ 為物件導向程式語言,物件中除了有物件自己的函數,也可以有物件自己的變數。 |
問題與討論 |
---|
1. 參數跟回傳值在函數中的用途為何?為什麼可以有多個參數,卻只能有一個回傳值? |
2. 在函數中可以改變參數的值嗎? |
3. 什麼是區域變數?為什麼說參數是區域變數? |
練習 |
---|
1. 寫一個程式 exercise0901.cpp ,裡頭設計一個函數 sum() ,用以計算兩個整數的和。 |
2. 承上題,另寫一個程式 exercise0902.cpp ,改成接受使用者輸入的版本。 |
3. 寫一個程式 exercise0903.cpp ,裡頭設計一個函數 sum() ,只用一個整數參數 p ,結果回傳 1 到 p 之間所有正整數的和。 |
4. 承上題,另寫一個程式 exercise0904.cpp ,改成接受使用者輸入的版本。 |
5. 寫一個程式 exercise0905.cpp ,裡頭設計一個函數 factorial() ,用以計算階層值。 |
6. 承上題,另寫一個程式 exercise0906.cpp ,改成用遞迴方式設計 factorial() 。 |
7. 承上題,另寫一個程式 exercise0907.cpp ,改成接受使用者輸入的版本。 |
8. 寫一個程式 exercise0908.cpp ,裡頭設計一個函數 fibonacci() ,用以計算費氏數列。 |
9. 承上題,另寫一個程式 exercise0909.cpp ,改成用遞迴方式設計 fibonacci() 。 |
10. 承上題,另寫一個程式 exercise0910.cpp ,改成接受使用者輸入的版本。 |