C 語言初學教材 - 第五章 四則運算器的函數版本

四則運算器可以分成兩個部份,其一是與使用者互動的介面,另一個則是單純的計算部份。我們之前把兩個部份混在一起,選擇計算子後直接顯示計算結果,其實計算部份可以單獨的抽離出來變成獨立的函數,使這個函數純粹做計算的工作,然後把結果顯示交給與使用者互動的部份。



因此,我們定義函數 calculator() ,接收三個參數,依序是第一個參數為整數型態的運算元,第二個字元型態的運算子,第三個也是整數型態的運算元。函數原型如下
int calculator(int a, char opt, int b); // 回傳四則運算的結果


函數定義如下
// 以下函數回傳四則運算的結果
int calculator(int a, char opt, int b)
{
    switch (opt) { 
        case '+':
            return a + b;

        case '-':
            return a - b;
            
        case '*':
            return a * b;

        case '/':
            return a / b;

        default:
            return 0; 
    }
}


因此,函數 calculator() 直接依第二個字元型態的運算子來選擇回傳哪個運算式的計算結果。 return 陳述中如果用運算式的話,回傳的會是運算式的計算結果,因此函數回傳的並非是整個運算式,而是運算式的計算結果。


此外留意這個函數就是單純的做計算工作,全部只用到一個 switch-case 複合陳述,這裡的 default 有點可有可無,在 default 後回傳 0 給呼叫函數。一般來說我們不會希望 default 的情況發生,但是接收使用者輸入的情況會比較複雜,我們採取保留 default 的設計方式,主要仍是在 switch-case 複合陳述維持一個預設選項。


至於檢查使用者輸入的情況交給與使用者互動的部份,我們寫在函數 main() 之中,全部的範例程式碼如下
#include <stdio.h>

int calculator(int a, char opt, int b); // 回傳四則運算的結果

int main(void)
{
    // 宣告需要用到的變數
    int a, b, t; 
    char opt;
    
    printf("這個程式會依符號計算兩個整數的和、差、積、商....\n");
    printf("請輸入計算式,如 2+2: "); // 提示使用者輸入的文字
    t = scanf("%d %c %d", &a, &opt, &b); // 如果輸入的型態相符, t == 3
    
    // 如果使用者輸入的除數為 0 ,將除數改為 1
    if (opt == '/' && b == 0) {
        b = 1;
    }
    
    // 以下印出結果
    if (t == 3 && (opt == '+' || opt == '-' || opt == '*' || opt == '/')) {
        printf("結果如下: \n");
        printf("%d %c %d = %d\n", a, opt, b, calculator(a, opt, b));
    }
    else {
        printf("輸入錯誤\n");
    }
    
    return 0;
}

// 以下函數回傳四則運算的結果
int calculator(int a, char opt, int b)
{
    switch (opt) { 
        case '+':
            return a + b;

        case '-':
            return a - b;
            
        case '*':
            return a * b;

        case '/':
            return a / b;

        default:
            return 0; 
    }
}


/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:fcal.c
    功能:接受使用者輸入的四則運算器
    作者:張凱慶
    時間:西元2010年7月 */


檢查的部份在第 21 行
// 以下印出結果
if (t == 3 && (opt == '+' || opt == '-' || opt == '*' || opt == '/')) {
    printf("結果如下: \n");
    printf("%d %c %d = %d\n", a, opt, b, calculator(a, opt, b));
}
else {
    printf("輸入錯誤\n");
}


變數 t 等於 3 ,並且運算子為 + 、 - 、 * 、 / 中的任一個,才會顯示出計算結果,不然就提醒使用者 "輸入錯誤" 。


注意我們在 printf() 的參數列之中呼叫 calculator() ,因為函數呼叫也是運算式之一,而且 calculator() 會回傳一個整數,這與我們放在 printf() 的參數列是相符的。


編譯後執行,結果如下



問題與討論
  1. 為什麼與使用者互動要交給函數 main() ,而不直接寫在 calculator() 中?
  2. 函數 calculator() 設計成單純的接受兩個整數型態的運算元及一個字元型態的運算子,試討論這樣設計的優劣。




沒有留言: