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。
習題
- 請問 5/2*2 和 5*2/2 的結果分別是什麼?為什麼?
- 若 n 是 int 型態的變數,請問
n - n/7*7 的結果是什麼 (與 n 和 7 有什麼關係)?
- 若 a b 分別是浮點數型態的變數,請問 a=5./9*4; 和
b=5/9*4.; 的結果分別是什麼?為什麼?
- 若 a b 分別是整數型態的變數,請問 a=5./9*4; 和
b=5/9*4.; 的結果分別是什麼?為什麼?
- 若 fahr = 68.9,請問
5/9*(fahr-32) 和 5*(fahr-32)/9 的結果分別是什麼?
- 試想 C 能否接受 a = 3*b = 3*5/2+3; 這樣的指令?
- c = (b==3)*c; 結果 c 是什麼?
而 c = b==3*c; 結果 c 是什麼?
又 (c = b)==3*c; 結果 c 是什麼?
單維彰 (2000/03/30) ---