C 教材:優先序與左右傾觀念

第一版的 mycat0.c 程式可以縮短成以下寫法。


#include <stdio.h>
 
/* 簡化的 UNIX cat 程式,第二版  (mycat.c) */
main() {
   int c;
 
   while ((c = getchar()) != EOF)
       putchar(c);
}

因為此時 while 的 BODY 只有一個指令,所以可以省略一對 { } 符號。 前面已經說過 === 的不同, 它們是兩種運算符號。考慮以下兩個語句:
2 + (3 * 5)   和   2 + 3 * 5
它們的結果相同。但是
(2 + 3) * 5   和   2 + 3 * 5
的結果就不同了。 這就要談到運算符號的優先順序 (precedence) 觀念。

在一對 ( ) 內的運算,優先度最高。這是大家習慣的符號用法。 但是,在沒標明 ( ) 的時候,哪個運算要先執行, 就要看哪個運算符號的優先度較高。 每個運算符號都有定義了優先度。 詳情以後再談。 現在我們至少要知道以下的優先度:

12:   *   /
11:   +   -
8:   ==   !=
1:   =
所以,上面的程式中,必須要寫
(c = getchar()) != EOF
才會讓 c 先定義成新讀入的字元,然後再比較 c 是否為 EOF。 如果寫成
c = getchar() != EOF
就會先比較新讀入的字元是否為 EOF,再將 c 定義成比較的結果: 也就是說,c 的值永遠是 0 或 1。 再換句話說,以下兩個語句是相同的:
c = getchar() != EOF   和   c = (getchar() != EOF)

運算符號除了定義優先度以外,還定義了左傾 (left to right associative) 或是右傾 (right to left associative)。 連續出現優先度相同的運算符號時,左傾的符號從左做到右, 右傾的符號從右做到左。以上提到的 * / + - == != 都是左傾,只有 = 是右傾。 例如

a = b = 3*5/2+3;
是先計算 ((3*5)/2)+3 得到 10 (整數計算), 然後將 b 定義成 10,再將 a 定義成 b 的值,也是 10。

習題

  1. 請問 5/2*25*2/2 的結果分別是什麼?為什麼?
  2. nint 型態的變數,請問 n - n/7*7 的結果是什麼 (與 n 和 7 有什麼關係)?
  3. a b 分別是浮點數型態的變數,請問 a=5./9*4;b=5/9*4.; 的結果分別是什麼?為什麼?
  4. a b 分別是整數型態的變數,請問 a=5./9*4;b=5/9*4.; 的結果分別是什麼?為什麼?
  5. fahr = 68.9,請問 5/9*(fahr-32)5*(fahr-32)/9 的結果分別是什麼?
  6. 試想 C 能否接受 a = 3*b = 3*5/2+3; 這樣的指令?
  7. c = (b==3)*c; 結果 c 是什麼? 而 c = b==3*c; 結果 c 是什麼? 又 (c = b)==3*c; 結果 c 是什麼?
[BCC16-C]
單維彰 (2000/03/30) ---
[Prev] [Next] [Up]