首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言運算符優先級教科書級誤區:單目運算符並非同級!sizeof 與類型轉換的優先級陷阱

     編輯:關於C語言

誤區來源:經典教材的錯誤表格

眾多國內 C 教材 (如譚浩強《C程序設計》) 附錄將 所有單目運算符歸為優先級 2、結合性右→左:

優先級 2 (單目運算符) :  !  ~  ++  --  -  (type)  *  &  sizeof  <-- 錯誤!全部同級

**這完全違背 C 標準**。實際上:sizeof、_Alignof、一元 &、*、+、-、~、! 屬於**一元運算符**,優先級**高於**類型轉換運算符 (type)。

實驗證明:悖論製造

int i = 3;
printf("%zu\n", sizeof (int *) & i); // 輸出 ?

按錯誤理論:sizeof、(int*)、& 同級右結合 → sizeof ((int*)&i) → 結果應等於 sizeof(int*) (4 或 8)。

實際運行 (GCC/MSVC):輸出 0 或 4 (視 i 值) —— 表達式被解析為 (sizeof (int *)) & i,即 **sizeof 結果與 i 做按位與**!

標準優先級層級 (C11 §6.5, 簡化版)

優先級 (高→低)運算符結合性備註
1() [] -> .左→右後綴/主運算符
2++ -- (type) * & + - ~ ! sizeof _Alignof右→左**一元運算符** (含 sizeof、類型轉換)
3* / %左→右乘法性
............

關鍵細節:雖同屬優先級 2,**結合性右→左意味著運算符只能作用於右側「優先級 ≥ 當前」的表達式**。

  • sizeof (int *):(int*) 是類型名 (非表達式),合法。
  • sizeof (int *) & i:sizeof 作用於右側 (int*) (高級表達式) 得到值,再與 i 做 & (二元按位與)。
  • 若想對 (int*)&i 取大小,**必須加括號**構成主表達式:sizeof ((int *)&i)。

概念釐清:高級表達式 vs 同級表達式

  • 高級表達式:相對某運算符,僅包含**更高優先級**運算符或基本表達式。如對 +,3*5 是高級表達式。
  • 同級表達式:不包含**更低優先級**運算符。如對 +,2+3 是同級,a=b 不是 (含 = 更低)。
  • 規則:運算符只能組合高級或同級表達式,並遵守結合性方向。

為什麼教材會錯?

  1. 過度簡化:「單目運算符」概念模糊了 sizeof (編譯期運算符) 與 (type) (類型轉換) 的本質區別。
  2. 缺乏「運算符只能作用於高級/同級表達式」這一核心語法規則的講解。
  3. 未驗證 sizeof (int *) & i 這類邊界案例。

總結與建議

**單目運算符優先級不完全相同**!sizeof、一元 &、* 等優先級**高於**類型轉換 (type)。遇到混合單目運算符表達式,**務必加括號**明確意圖,勿信直覺與錯誤表格。

推薦參考:cppreference Operator Precedence — 權威、機器可驗證、持續更新。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved