# 簡易介紹C/C++中&, &&, |, ||的差別 * 在初學時,我們很常使用上述的符號來做IF的邏輯運算,例如以下範例: ```cpp int main() { bool IsKoreaFishLazy = true; bool IsKaohsiungRich = false; if(IsKaohsiungRich && IsKoreaFishLazy) cout<<"a"; if(IsKaohsiungRich & IsKoreaFishLazy) cout<<"b"; if(IsKaohsiungRich || IsKoreaFishLazy) cout<<"c"; if(IsKaohsiungRich | IsKoreaFishLazy) cout<<"d"; } ``` ``` Output: cd ``` * 從簡單的true/false判斷來看,乍看下好像是等價,但是實際上兩者是有相當大的差別的。 ## (&,|) 算術運算子 * &與|是"算術運算子",意思就是這兩個符號是用在對於bit的運算,&對應至"AND",而|則是對應至"or",例如說以下面的bit運算為例: * (*註: bitset函式的作用是把數值以2進位顯示) ```cpp int main() { int a = 4; int b = -5; int c = a & b; int d = a | b; cout<<"a= "<<std::bitset<8>(a)<<endl; cout<<"b= "<<std::bitset<8>(b)<<endl; cout<<"c= "<<std::bitset<8>(c)<<endl; cout<<"d= "<<std::bitset<8>(d)<<endl; } ``` * Output: ``` a= 00000100 b= 11111011 c= 00000000 d= 11111111 ``` ## (&&,||) 邏輯運算子 * 而&&與||則是邏輯運算子,就是用來判斷true與false的狀態,如同最上面的if/else的例子,想當然而就不能拿來當作算術運算子來使用...嗎? ```cpp int main() { int a = 4; int b = -5; int c = a && b; int d = a || b; cout<<"a= "<<std::bitset<8>(a)<<endl; cout<<"b= "<<std::bitset<8>(b)<<endl; cout<<"c= "<<c<<endl; cout<<"d= "<<d<<endl; cout<<"c's hex= "<<std::bitset<8>(c)<<endl; cout<<"d's hex= "<<std::bitset<8>(d)<<endl; } ``` * Output: ``` a= 00000100 b= 11111011 c= 1 d= 1 c's hex= 00000001 d's hex= 00000001 ``` * 其實編譯還是會過的哦,但是結果很明顯跟算術運算子的結果不太一樣,從這個例子可以看出與算術運算子的差別以及一些規律。 * **只要是數值不為0,系統在邏輯運算上就會把它視為"true",反之則是"false"。** * **而"true"在二進位之值為"1",反之"false"為"0"**,以下有測試結果: ```cpp int main() { bool IsKoreaFishLazy = true; bool IsKaohsiungRich = false; cout<<std::bitset<8>(IsKoreaFishLazy)<<endl; cout<<std::bitset<8>(IsKaohsiungRich )<<endl; } ``` ``` 00000001 00000000 ``` ## 雖然知道底層的原理,但我們在條件判斷if/else上,好像還是可以混用啊? * 照上面的邏輯,我們再回到if/else判斷式範例: ```cpp int main() { bool IsKoreaFishLazy = true; bool IsKaohsiungRich = false; if(IsKaohsiungRich && IsKoreaFishLazy) cout<<"a"; if(IsKaohsiungRich & IsKoreaFishLazy) cout<<"b"; if(IsKaohsiungRich || IsKoreaFishLazy) cout<<"c"; if(IsKaohsiungRich | IsKoreaFishLazy) cout<<"d"; } ``` * 套用剛剛的結論,一個是把數值做bit做and/or運算,一個是轉成true/false判斷,在變數是單純的bool下這兩者結果是完全沒差的。 * 但此篇最重要的結論來了: **在AND的情況下,算術運算子&&因為bit運算的關係,一定會存取兩個變數並運算出結果,而邏輯運算值&只要第一個變數是false,就會直接跳出if判斷式** * 也就是說,if(IsKaohsiungRich && IsKoreaFishLazy)會讀取兩個變數的值(0與1)並且做AND運算,而if(IsKaohsiungRich & IsKoreaFishLazy)只要看到IsKaohsiungRich為false/0就會跳出了。 ## 不是阿,除了效率問題外,我還是可以混著用啊? * 當然不行,在某些狀況下是差很多的,以[此題leetcode為例](https://leetcode.com/explore/interview/card/top-interview-questions-easy/93/linked-list/560/),為了判斷linklist中,目前指標指向的node以及此node串接的下個node是否為NULL,我需要以下的判斷式: ```cpp if(head != nullptr && head -> next != nullptr) ``` * 在head為nullptr的情況下,假如說你使用&,讓兩邊的bool做and運算,第二個bool(head -> next != nullptr)會因為head為nullptr的情況下,我又想去access head,導致編譯器彈出錯誤: ``` Runtime Error Message: Line 12: Char 38: runtime error: member access within null pointer of type 'struct ListNode' (solution.cpp) Last executed input: [] ``` * 使用&&的話,只要看到我指向的head為nullptr就直接跳出了if,自然就不會有access nullptr的問題囉。 * 所以除了特殊狀況下,還是乖乖使用邏輯運算子吧! ## 延伸資料 * [codepad 好用的線上編譯器](http://codepad.org/) * [C++ bool 所占的記憶體空間與資料對齊 (data alignment)](https://www.cclo.idv.tw/blogs/closer/?p=184)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.