C 語言初學教材 - 第二章 小心!除以 0

如果在四則運算器中將某個整數除以 0 ,那會發生什麼結果呢?




執行後顯示 Floating point exception 的錯誤,然後中斷程式的執行,現在許多已經開發成熟的作業系統大多會這麼做,可以片面單獨終止某一程式,避免整個系統崩潰。除以 0 對電腦而言是致命錯誤,就是說發生除以 0 的情況,程式變無法繼續運作,導致程式當掉,或是整個系統當機。


數學上我們學到 0 不能當分母的規則,這是因為 0 當除數會使算式變得沒有意義,在電腦中除以 0 會無法運算出結果,所以我們得小心使用可能會發生這樣結果的程式,嗯,小心使用固然是個辦法啦!但我們總是不能預期使用者如何使用,因此在程式中加入防範的機制,便是另一個可行的辦法。


我們提供一個簡單的防範機制,也就是測試使用者輸入的除數是否為 0 ,如果是 0 ,就把除數改為 1 。程式碼如下
#include <stdio.h>

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

        case '-':
            printf("%d - %d = %d\n", a, b, a - b);
            break;

        case '*':
            printf("%d * %d = %d\n", a, b, a * b);
            break;

        case '/':
            printf("%d / %d = %d\n", a, b, a / b);
            break;

        default:
            printf("輸入錯誤!\n");
            break;
    }
    
    return 0;
}

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


防範機制設置在第 13 行到第 15 行
//如果使用者輸入的除數為 0 ,將除數改為 1
if (b == 0) {
    b = 1;
}


第 12 行的註釋說明這段程式碼的作用。這裡引入兩個新觀念,首先是 if 陳述,用法圖解如下



if 後可接複合陳述,大括弧後不需要以分號結尾。


if 為關鍵字之一,主要用為條件選擇,提供程式執行分流之用。 if 後接小括弧,小括弧中即為條件,所謂的條件其實就是運算式,運算結果為非 0 的值,就會執行 if 底下大括弧的陳述,若運算結果為 0 ,程式就會跳過大括弧,繼續執行大括弧後的程式。


條件的用語是個邏輯概念,若真,做 A 工作,若假,做 B 工作。在 C 語言中,所有非 0 的值皆為真,包括負數,只有 0 是假。


另一個新觀念就是我們用了新的運算子,條件是 opt == '/' && b == 0 ,這個運算式分成兩部份,利用連續兩個 && 連接,我們先來看看 && 之前的 opt == '/' 與之後的 b == 0 。

opt == '/' 的意思就是測試 opt 是否等於 '/' ,而 b == 0 的意思則是測試 b 是否等於 0 。測試結果若相等,計算結果為 1 ,若測試後不相等,,計算結果就為 0 。連續兩個等號 == 為測試相等的運算子,這是 C 語言六個關係運算子之一
運算子功能範例
<小於a < b
<=小於等於a <= b
>大於a > b
<=大於等於a <= b
==相等a == b
!=不等a != b


C 語言中,單一個等號 = 用作指派,而連續兩個等號用作 == 測試相等。


連續兩個 && 則是邏輯運算子中的「且」,就是說兩個運算元都為真,邏輯「且」才為真。 C 語言共有三個邏輯運算子
運算子功能範例
!!a
&&a && b
||a || b


所以這個條件 opt == '/' && b == 0 算是比較複雜的運算式,程式會先計算 opt == '/' 的值,然後碰到 && ,這時候,若 opt == '/' 為假,也就是計算結果為 0 ,整個條件運算式的結果就會為假,程式直接跳過 if 底下的大括弧。除非 opt == '/' 為真,程式才會繼續測試 b 是否等於 0 ,若 b 等於 0 , if 底下的大括弧才會被執行。

C 語言這項特性被稱為 short-circuit evaluation ,中文可稱之為短路徑計算,若妥善利用邏輯運算子與這項特性,對於提升程式效能是很有幫助的。


我們來編譯執行看看吧!



問題與討論
  1. 討論設計防範機制與小心使用的優劣。
  2. 若使用者誤將除數輸入 0 ,程式主動將 0 改成 1 ,這麼做恰不恰當?
  3. 承上例,如果不改為 1 ,那應該怎麼做呢?
  4. 邏輯運算分成且、或、非三種,請畫出三種邏輯運算的真值表。
  5. 我們把 if 陳述後的小括弧稱為條件, switch 陳述後的小括弧也是運算式,可否稱為條件呢?




沒有留言: