發信人: ax.bbs@bbs.ee.nthu.edu.tw. (athena), 信區: test
標  題: 星星流講座 0006
發信站: ☆清華電機☆ (Thu May  4 00:29:37 1995)
轉信站: star

星星流講座 0006         C 語言教室

第 2 講 之 3            Arithmetic Operations
                        Topic: 進階的運算子和數的值域

算術運算中我們常常要做的就是指定 (assignment) 的動作,也就是把等
號右邊的數值指定給等號左邊的數。指定運算子 (assignment operator)
最常用的就是等號 = 。

在 C 語言中,為了方便的因素,增加了許多指定運算子,它們的用法和功能
請看下面的對照表你就很容易可以了解了:

        原來的指定運算式        比較簡單的指定運算式

        a = a + b;              a += b;
        a = a - b;              a -= b;
        a = a * b;              a *= b;
        a = a / b;              a /= b;
        a = a % b;              a %= b;
 

請注意的是 += 這類符號中 + 和 = 中間是沒有空格的。

由於我們在程式中常常會用到像 a = a + 1 或 a = a - 1 這種式子,所以 C
特別提供了兩個運算子:遞增運算子 (increment operator) ++ 和遞減運算子
(decrement operator) --。它們的意義如下:

        原來的指定運算式        比較簡單的指定運算式

        a = a + 1;              a++; 或 ++a;
        a = a - 1;              a--; 或 --a;
 

你心裡也許有個疑問:++ 放前面 (prefix) 和放後面 (postfix) 有什麼不同?
++a 表示先把 a 加 1,再把 a 丟給取用它的式子; a++ 表示先把 a 丟給
取用它的式子,再把 a 加 1
。我們以後講解陣列的時候,會以詳細的例子
提醒各位這個陷阱。

到目前為止我們已經介紹了基本的數值型態,以及和數值運算相關的運算子,現
在我們來看看如何得知數值型態所能表示的範圍:
 

/* range.c */

#include <stdio.h>

main ()
{
    printf ("%d %d %d\n", sizeof (short), sizeof (int), sizeof (long));
    printf ("%d %d %d\n", sizeof (float), sizeof (double),\
            sizeof (long double));
}

執行結果 (on Sun SPARC 10)

2 4 4
4 8 8

首先說明 sizeof 的意思:sizeof 是一個特別的運算子,它用來傳回某個型態一
共佔掉了記憶體空間多少 byte。像我們的例子中,short 型態佔了 2 bytes,int
型態則佔了 4 bytes ..... 等等。值得注意的是,每種基本的數值資料型態所佔
的 byte 數取決於機器的設計,不同的機器、不同的編譯器均可能導致不同的結果


我們知道了每種數值資料型態的長度之後,便可以很輕易地求出它的值域了,例如:

          型態    長度 (bits)     值域

                                    15     15
signed    short   16              -2   ~ +2  - 1  => -32768 ~ +32767
          int     32              -214783648 ~ 214783647
unsigned  short   16              0 ~ 65535
          int     32              0 ~ 4294967295

                                           -38            +38
          float   32              ±3.4×10    ~ ±3.4×10
                                  (精確度小數點後 7 位)

                                           -308            +308
          double  64              ±1.7×10     ~ ±1.7×10
                                  (精確度小數點後 15 位)

目前幾乎所有的編譯器和電腦硬體都是支援 IEEE 的浮點數標準,所以浮點數都當
成有號數來處理,無號浮點數是沒有意義的。值域的詳細求法請參考計算機結構方
面的書籍,這不是我們研究 C 語言的重點所在 ^_^。

在數值運算中,如果給定的數值超過了變數的數值型態所能表示的範圍,就會產生
溢位 (Overflow),例如:

        short a;
        a = 90000;      /* overflow */

浮點數運算中,求出來的值太小使得數值不能控制在精確度所能表示的範圍,會產
生缺位 (Underflow)。缺位的情形比較少見。

數值運算除了溢位和缺位之外,還有一種常見的運算錯誤,那就是除以 0 (Divide
by zero)。我們在寫程式的時候要仔細考慮數值運算可不可能發生這三種錯誤,如
果可能那麼必須想辦法在程式中消除它,因為這些錯誤都會觸發電腦的硬體產生錯
誤訊號而直接停掉你的程式,嚴重的話可能導致當機。