C 語言擁有極其豐富的運算符體系,這是其功能強大、表達靈活的核心特徵之一。運算符不僅有優先級之分,更具備結合性(左結合/右結合)特性,決定同優先級運算符的運算順序,這在高級語言中較為少見,也增加了理解複雜度。
+ - * / % ++ --(7種)> < == >= <= !=(6種)&& || !(3種)& | ~ ^ << >>(6種)=、復合算術 += -= *= /= %=、復合位運算 &= |= ^= >>= <<=(共11種)?:(三目運算符),* &sizeof() [] -> .C 語言運算符優先級共 15 級,第1級最高,第15級最低。表達式求值遵循:
+ - * / %,例:x - y + z 先算 x - y 再加 z。=,例:x = y = z 先算 y = z 再算 x = (y = z)。單目運算符(++ -- ! ~ * & sizeof)、條件運算符 ?: 亦為右結合。大量運算符為右結合,閱讀代碼時務必區分,避免誤解。
| 運算符 | 目數 | 結合性 | 備註 |
|---|---|---|---|
+ | 雙目 | 右結合 | 加法 |
- | 雙目/單目 | 左結合 | 減法/負值 |
* | 雙目 | 左結合 | 乘法 |
/ | 雙目 | 左結合 | 整數相除捨去小數;含實數則結果為雙精度實數 |
% | 雙目 | 左結合 | 求餘(模運算),雙方必為整數 |
void main() {
printf("\n\n%d,%d\n", 20/7, -20/7); // 輸出 2, -2(捨去小數)
printf("%f,%f\n", 20.0/7, -20.0/7); // 輸出 2.857..., -2.857...
}
void main() {
printf("%d\n", 100 % 3); // 輸出 1
}
++、--)單目運算,右結合性。四種形式語義差異極大,易出錯:
| 形式 | 操作順序 | 參與運算的值 |
|---|---|---|
++i | 先自增1 | 增後的值 |
--i | 先自減1 | 減後的值 |
i++ | 先參與運算,後自增1 | 原值 |
i-- | 先參與運算,後自減1 | 原值 |
void main() {
int i = 8;
printf("%d\n", ++i); // 9
printf("%d\n", --i); // 8
printf("%d\n", i++); // 8 (輸出後 i=9)
printf("%d\n", i--); // 9 (輸出後 i=8)
printf("%d\n", -i++); // -8 (輸出 -8,i=9)
printf("%d\n", -i--); // -9 (輸出 -9,i=8)
}
void main() {
int i = 5, j = 5, p, q;
p = (i++) + (i++) + (i++); // p = 5+6+7 = 18? 實際為 15 (三個舊值相加),最後 i=8
q = (++j) + (++j) + (++j); // q = 6+7+8 = 21? 實際為 24 (三個新值相加),最後 j=8
printf("%d,%d,%d,%d", p, q, i, j);
}
關鍵:i++ 在同一表達式多次出現時,行為屬於未定義序列點(C標準未規定求值順序),不同編譯器結果可能不同,實務中應避免此類寫法。
=變數 = 表達式a = b = c = 5 等價 a = (b = (c = 5))。= 定義為運算符,構成賦值表達式,可出現於表達式合法的任何位置,如 x = (a = 5) + (b = 8) 合法,x 得 13。x = 8; a = b = c = 5;void main() {
int a, b = 322;
float x, y = 8.88;
char c1 = 'k', c2;
a = y; // a = 8
x = b; // x = 322.0
a = c1; // a = 'k' 的 ASCII 碼 107
c2 = b; // c2 = 322 低8位 = 66 ('B')
printf("%d,%f,%d,%c", a, x, a, c2);
}
形式:變數 雙目運算符= 表達式,等價 變數 = 變數 運算符 表達式。
例:a += 5 ≡ a = a + 5;x *= y + 7 ≡ x = x * (y + 7)。
優點:有利於編譯器優化,生成更高效目標代碼。
表達式1, 表達式2exp1, exp2, ..., expn,整體值為 expn。for 循環的初始化/遞增部分。void main() {
int a = 2, b = 4, c = 6, x, y;
y = (x = a + b), (b + c); // x=6, y=10 (整體值為 b+c)
printf("y=%d, x=%d", y, x);
}
精通 C 語言運算符需掌握:分類用途、優先級層級、結合性方向、類型轉換規則、副作用運算符(++/--/賦值)的求值順序陷阱。複雜表達式建議拆分為多語句,提升可讀性與可靠性。