C++ 入門指南 4.01

單元 9 - 函數

-unit9-

函數 (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 ,參數數量則是依需求自己定義,這裡為兩個 ab ,型態都是 int

這裡, ab 都是屬於 big() 內的區域變數 (local variable) ,也就是效力僅限於 big() 後的大括弧中。

也可以不定義參數,這時參數列可宣告為 void 或留空白。

此例用了兩個 return ,有回傳值的函數至少要有一個 returnreturn 就是函數結束執行,將控制權交還原本呼叫函數的地方, 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;

編譯後執行,結果如下

-bigdemo-

上例只有在 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(); // 印出空白一行

編譯執行的結果是一樣的

-printdemo-

函數是最基本也是最簡單的功能模組,可是 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 ,結果回傳 1p 之間所有正整數的和。 參考程式碼
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 ,改成接受使用者輸入的版本。 參考程式碼

相關教學影片

上一頁 單元 8 - 迴圈
回 C++ 入門指南 4.01 目錄
下一頁 單元 10 - 類別
回 C++ 教材
回程式語言教材首頁