int a = 1 | 0 == 1 & 0;
等價於(1 | 0) == (1 & 0)
,計算的結果為0
。
==
優先順序高於位操作符
等價於1 | ((0 == 1) & 0))
,計算的結果為1
。
||
操作符與==
操作符的優先順序關係問題是這樣產生的。在 c 的早期,&
和&&
合用同乙個操作符,|
和||
也是如此(明白嗎?)。 它繼承了 b 和 bcpl 中的概念「真值上下文」。就是在if
和while
等後面需要乙個布林值的時候,&
和丨
就被翻譯成現在的&&
和||
。如果它們在一般的表示式裡,就被解釋成位操作符,也就是現在的樣子。這個機制操作起來沒有問題,但理解起來很困難(在真值上下文裡,存在「頂層運算子」的概念)。
&
和|
的優先順序跟現在一樣。最初,在 alan snyder 的催促下,我在c語言中加入了&&
和||
操作符。這就成功地把位運算的概念和布林運算的概念分了開來。然而,我心懷不安,因為我意識到了優先順序的問題。例如,在現存的大量程式中,存在諸如這樣的表示式:if(a == b & c == d)
。
事後回想,如果我們一開始就改變優先順序,讓&
的優先順序高於==
,在邏輯上可能更清晰一些。但是,從安全的角度出度,只能做到把&
和&&
分開這個程度,無法在兩者的優先順序之間再插入其他的操作符(否則的話,現有的大量**都有可能出問題)。
表示式人們可能誤以為的結果
實際結果
.的優先順序高於*。->優先順序用於消除這個問題
*p.f
p所指物件的字段f。 (*p).f
對p取f偏移,作為指標,然後進行間接引用操作。*(p.f)
高於*int *ap
ap是個指向int陣列的指標。int(*ap)
ap是個元素為int指標的陣列。int *(ap)
函式()高於*
int *fp()
fp是個函式指標,所指函式返回int。int (*fp)()
fp是個函式,返回int。int(fp())
==和!=高於位操作符
(val & mask != 0)
(val & mask)!= 0
val & (mask != 0)
==和!=高於賦值符
c=getchar()!=eof
(c=getchar())!=eof
c=(getchar()!=eof)
算術運算子高於移位運算子
msb << 4 + lsb
(msb << 4) + lsb
msb << (4 + lsb)
逗號運算子在所有運算子中優先順序最低
i=1,2
i=(1,2)
(i=1),2
運算子優先順序 C 運算子優先順序
c 運算子優先順序 優先順序運算子 描述方向1 scope resolution 範圍解析 left to right 2 suffix postfix increment and decrement 字首 字尾遞增和遞減 function call 函式呼叫 array subscripting ...
運算子優先順序 Python 運算子優先順序
python 運算子優先順序 運算子描述 lambda lambda表示式 or布林 或 and布林 與 not x 布林 非 in,not in 成員測試 is,is not 同一性測試 比較 按位或 按位異或 按位與 移位 加法與減法 乘法 除法與取餘 x,x 正負號 x 按位翻轉 指數 x.a...
運算子優先順序 PHP運算子優先順序
php運算子優先順序 結合方向 運算子附加資訊 非結合clone new clone 和 new左 array 非結合 遞增 遞減運算子 非結合 int float string array object bool 型別非結合 instanceof 型別右結合 邏輯操作符 左 算術運算子 左 算術運...