這兩種情況很可能產生相同的機器代碼,或者非常接近的東西。所以選擇哪一個是編碼風格的問題。
我會說,如果操作很複雜,以至於它們不會輕易放在一條線上,那麼if
-else if
就更好了。否則,如果操作有些簡單,||
版本可能更喜歡。雖然這是相當主觀的。
關於這些運營商的內部運作的高級討論如下。如果你對這些事情不感興趣,你可能會停止閱讀。
然而,也有一些細節,使這兩個版本非常輕微的不同。在這兩種情況下,每個單獨的操作數都是使用類型平衡隱式提升的。但是在||
的情況下,存在額外的隱式促銷發生:
0123'的結果與(x && !y && !z)
的結果相平衡。最終,結果是具有最大轉換等級的操作數的類型。
重要嗎?我不明白在這個具體情況下會如何。但是讓我們說,我們有這樣的事情:
uint8_t x;
uint8_t y;
uint32_t z;
然後我們有一個表達:
if((x && y) || (x && z))
// or
if(x && y)
{}
else if(x && z)
{}
讓我們假設我們使用的是8位或16位CPU,其中int
爲16位。
在如果其他情況下,會發生以下情況:
- x和y均爲整數
uint8_t
晉升爲int
,因爲它們是小的整數類型。
- 表達式
(int)x && (int)y
是平衡的。 x && y
根據類型int
計算,結果爲int
。
- 在表達式
x && z
,x
是如上所述的整數提升,但不是z
,它不是一個小整數類型並且仍然是uint32_t
。
- 表達式
(int)x && (uint32_t)z
是平衡的,然後計算uint32_t
類型。結果是uint32_t
。
- 因此
x && y
總是在一個16位變量上計算,而x && z
總是在一個32位變量上計算。
如果我們看||
版本,也會發生同樣的情況。但是接下來我們有另外一種額外的平衡:(uint16_t)first_result || (uint32_t)second_result
。這種平衡由於||
運營商而得到強制執行。這意味着如果x==true
和y==true
,那麼整個操作的結果將是uint32_t
類型。
但在if-else版本中,x && y
類型始終爲uint16_t
。 ||
版本在x
類型和z
類型之間引入了隱蔽的緊密耦合。
無論編譯器是否能夠有效優化||
場景,我都不知道。我期望它,但是由於編譯器不能對整個表達式的結果做出編譯時決定,因爲它不知道操作數是真是假,它可能只是最終全部執行它在32位類型上。如果我們有一個8位或者16位的CPU,這將是一個壞消息,它會非常低效地處理32位數。
代碼的第二部分將不會有所不同。我會假設編譯器會優化它。作爲一個幫助:推薦使用按位運算符可能值得一些解釋 –