【C++ 筆記】運算子(下) - part 5 === 目錄(Table of Contents): [TOC] --- 很感謝你點進來這篇文章。 你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧! 運算子(Operator) --- 讓我們回顧 part 3 內容, C++ 有支援以下運算子: * 算術運算子 - part 3 已學過 * 關係運算子 - part 3 已學過 * 邏輯運算子 * 位元運算子 * 指定運算子 * 運算元(Operand):在運算式中,運算元是資料的值。在例子「1 + 1」當中,兩個「1」都是運算元,運算元是被操作、運算的物件。 * 運算子(Operator):運算子是一個進行操作的符號。在例子「1 + 1」當中,「+」就是一個運算子,表示加法操作、運算。 * 運算式(Expression):運算式是由運算元和運算子組成的結構,用於進行計算並回傳結果。在例子中,「1 + 1」就是一個運算式,進行加法運算並回傳結果為「2」。 算術運算子:就是數學運算子,+、-、*、/、%、++、-- 等運算子。 關係運算子(比較運算子): | 運算子 | 描述 | | -------- | -------- | | == | 比較兩個運算元是否相等。是則回傳 true,不是則回傳 false。 | | != | 比較兩個運算元是否「***不***」相等。是則回傳 true,不是則回傳 false。 | | > | 比較左運算元是否大於右運算元。是則回傳 true,不是則回傳 false。 | | < | 比較左運算元是否小於右運算元。是則回傳 true,不是則回傳 false。 | | >= | 比較左運算元是否「***大於或等於***」右運算元。是則回傳 true,不是則回傳 false。 | | <= | 比較左運算元是否「***小於或等於***」右運算元。是則回傳 true,不是則回傳 false。 | ### 邏輯運算子(Logical Operator) --- | 運算子 | 描述 | | -------- | -------- | | && | 邏輯 AND 運算子,如果兩個運算元都是 true,則條件為 true。 | | || | 邏輯 OR 運算子,如果兩個運算元中其中一個是 true,則條件為 true。 | | ! | 邏輯 NOT 運算子,主要用來反轉邏輯狀態的運算子,像是 (A&&B) 若為 true,則 !(A&&B) 為 false。 | ![image](https://hackmd.io/_uploads/SJddXTuVR.png) Image Source:[Advanced Search Techni... | Klingemann Library LibGuides](https://libguides.berlin-international.de/books/how-to-search/page/advanced-search-techniques) 以上是 AND、OR、NOT 運算子它們的文氏圖,總之文氏圖的意義在程式語言的 &&、||、! 運算是一樣的。 邏輯運算子主要應用在 if、else if 等等的條件語句當中,具體來說是如何應用呢? 仍然老話一句,繼續練習吧! ```cpp= #include<iostream> using namespace std; int main(){ int a = 10, b = 20; if (a == 10 && b == 20){ cout << "True" << endl; } else{ cout << "False" << endl; } a = 5; if (a == 10 && b == 20){ cout << "True" << endl; } else{ cout << "False" << endl; } } ``` 輸出結果: ``` True False ``` 接下來是 || 邏輯 OR 運算子的範例: ```cpp= #include<iostream> using namespace std; int main(){ int a = 10, b = 20; if (a == 10 || b == 20){ cout << "True" << endl; } else{ cout << "False" << endl; } a = 5; if (a == 10 || b == 20){ cout << "True" << endl; } else{ cout << "False" << endl; } } ``` 輸出結果: ``` True True ``` 接下來是 ! 邏輯 NOT 運算子的範例: ```cpp= #include<iostream> using namespace std; int main(){ int a = 10, b = 20; if (!(a == 10 && b == 20)){ cout << "True" << endl; } else{ cout << "False" << endl; } a = 5; if (!(a == 10 || b == 20)){ cout << "True" << endl; } else{ cout << "False" << endl; } } ``` 輸出結果: ``` False False ``` 結合 &&、|| 運算子,能夠新增更多的條件,避免產生 if 巢狀判斷的情況,比如說以上面範例的 && 運算子舉例,如下程式碼: ```cpp= #include<iostream> using namespace std; int main(){ int a = 10, b = 20; if (a == 10){ if (b == 20){ cout << "True" << endl; } } else{ cout << "False" << endl; } a = 5; if (a == 10){ if (b == 20){ cout << "True" << endl; } } else{ cout << "False" << endl; } } ``` 輸出結果: ``` True False ``` 以上程式碼適用於 && 運算子的巢狀判斷寫法,至於 || 運算子的寫法,我想各位讀者可以自己玩看看。 ### 位元運算子(Bitwise Operator) --- C++ 當中,提供了 AND(&)、OR(|)、NOT(!)、XOR(^)、補數(~)complement 等位元運算子。 * AND 表示兩真值成立才得以成立,也就是運算元都必須是 1。 * OR 表示兩真值其中之一個成立就可以成立,也就是所有運算元當中其中一個是 1 即可成立。 * NOT 表示反轉邏輯,如 AND 運算過後的結果是 1,則使用 ! NOT 運算子會讓它變成 0。 * XOR 表示兩真值其中之一個成立就可以成立,***且必須沒有交集***,交集意思就是 1、1,0、0,兩個運算元是有相同的值。 二進位轉換器:[即時十進位轉二進位轉換器 - Yeecord 小工具](https://tools.yeecord.com/zh-tw/base-converter/dec/bin) 二進位轉十進位徒手算法: 假設 1100100,從最右邊的 0 開始,為 0*2的0次方,左邊下一個也是 0,為 0*2的1次方,以此類推,之後將這些值全部相加,得總和就能算出十進位的數字。 假設 A = 100、B = 87。 則 A、B 二進位分別為: A = 1100100 B = 1010111 A & B = 1000100 = 十進位的 68 A | B = 1110111 = 十進位的 119 A ^ B = 0110011 = 十進位的 51 ~A = 0011011 = 十進位的 27 註:補數(~)complement 將二進位的 0 轉換成 1,1 轉換成 0,就這樣,就是整個把它顛倒過來。 ![A&B文氏圖](https://hackmd.io/_uploads/SyHk1dFV0.jpg) ***以上是 A & B 文氏圖,作者繪製。*** ![AORB文氏圖](https://hackmd.io/_uploads/H1VyyutEA.jpg) ***以上是 A OR B 文氏圖,作者繪製。*** ![AXORB文氏圖](https://hackmd.io/_uploads/rJVy1uKER.jpg) ***以上是 A XOR B 文氏圖,作者繪製。*** 接下來讓我們針對以上的運算子來進行練習~~(範例取自:[邏輯運算、位元運算](https://openhome.cc/Gossip/CppGossip/LogicalBitwise.html)) ```cpp= #include <iostream> using namespace std; int main() { cout << "AND 運算:" << endl; cout << "0 AND 0\t\t" << (0 & 0) << endl; cout << "0 AND 1\t\t" << (0 & 1) << endl; cout << "1 AND 0\t\t" << (1 & 0) << endl; cout << "1 AND 1\t\t" << (1 & 1) << endl; cout << "OR 運算:" << endl; cout << "0 OR 0\t\t" << (0 | 0) << endl; cout << "0 OR 1\t\t" << (0 | 1) << endl; cout << "1 OR 0\t\t" << (1 | 0) << endl; cout << "1 OR 1\t\t" << (1 | 1) << endl; cout << "XOR 運算:" << endl; cout << "0 XOR 0\t\t" << (0 ^ 0) << endl; cout << "0 XOR 1\t\t" << (0 ^ 1) << endl; cout << "1 XOR 0\t\t" << (1 ^ 0) << endl; cout << "1 XOR 1\t\t" << (1 ^ 1) << endl; cout << "NOT 運算:" << endl; cout << "NOT 0\t\t" << (!0) << endl; cout << "NOT 1\t\t" << (!1) << endl; return 0; } ``` 輸出結果: ``` AND 運算: 0 AND 0 0 0 AND 1 0 1 AND 0 0 1 AND 1 1 OR 運算: 0 OR 0 0 0 OR 1 1 1 OR 0 1 1 OR 1 1 XOR 運算: 0 XOR 0 0 0 XOR 1 1 1 XOR 0 1 1 XOR 1 0 NOT 運算: NOT 0 1 NOT 1 0 ``` 以下是利用位元運算判斷偶、奇數的程式碼(範例取自:[邏輯運算、位元運算](https://openhome.cc/Gossip/CppGossip/LogicalBitwise.html)): ```cpp= #include <iostream> using namespace std; int main() { int input = 0; cout << "輸入正整數:"; cin >> input; cout << "輸入為奇數?" << (input & 1 ? 'Y' : 'N') << endl; return 0; } ``` 輸出結果: ``` 輸入正整數:5 輸入為奇數?Y ``` > 這個程式的原理是,奇數的數值若以二進位來表示,其最右邊的位元必為 1,而偶數最右邊的位元必為 0,所以使用 1 來與輸入的值作 AND 運算,由於 1 除了最右邊的位元為 1 之外,其它位元都會是 0,與輸入數值 AND 運算的結果,只會留下最右邊位元為 0 或為的結果,其它部份都被 0 AND 運算遮掉了。 總之,讓輸入的數字跟二進位 " 1 ",注意喔,只有 1 而已,所以它只會跟最二進位的最右邊位元進行運算。 而最右邊的位元我們剛剛說過,轉換成十進位會變成 1 * 2 的 0 次方,也就是會變成 1,而如果位元是 0 的話就是 0 * 2 的 0 次方,變成 0。 1 是奇數,0 是偶數。 然後讓我們介紹一下左移、右移運算子(<<、>>)。 「<<」:左移運算子,將一個運算物件的各二進位位元全部左移某位元(左邊的位元放棄,右邊補 0)。 「>>」:右移運算子,將一個運算物件的各二進位位元全部右移某位元(右邊的位元放棄,正數左邊補 0、負數左邊補 1)。 舉例:a = 60,二進位為 0011 1100。 則 a << 2 表示全部往左移兩位:1111 0000。 則 a >> 2 表示全部往右移兩位:0000 1111。 練習一下: ```cpp= #include <iostream> using namespace std; int main() { int a = 60, c = 0; c = a << 2; // 240 = 1111 0000 cout << "a 進行左移後 c is : " << c << endl ; c = a >> 2; // 15 = 0000 1111 cout << "a 進行右移後 c is : " << c << endl ; return 0; } ``` 輸出結果: ``` a 進行左移後 c is : 240 a 進行右移後 c is : 15 ``` 別睡著了! 哈囉,你還醒著嗎? 看起來還醒著,讓我們繼續吧! ### 指定運算子(Assignment Operator) --- 指定運算子就是用於簡化變數指定流程的一種運算子,以下是個表格: | 運算子 | 描述 | 實例 | | -------- | -------- | -------- | | = | 指定運算子。 | c = a + b,將 a + b 運算過後指定給 C。 | | += | 加和指定運算子。 | c += a 等於 c = c + a。 | | -= | 減和指定運算子。 | c -= a 等於 c = c - a。 | | *= | 乘和指定運算子。 | c *= a 等於 c = c * a。 | | /= | 除和指定運算子 | c /= a 等於 c = c / a。 | | %= | 取模和指定運算子。 | c %= a 等於 c = c % a。 | | <<= | 左移和指定運算子。 | c <<= a 等於 c = c << a。 | | >>= | 右移和指定運算子。 | c >>= a 等於 c = c >> a。 | | &= | AND位元運算子和指定運算子。 | c &= a 等於 c = c & a。 | | ^= | XOR位元運算子和指定運算子。 | c ^= a 等於 c = c ^ a。 | | |= | OR位元運算子和指定運算子。 | c |= a 等於 c = c | a。 | 練習一下: ```cpp= #include <iostream> using namespace std; int main() { int a = 21; int c ; cout << "初始值 a = " << a << endl; c = a; cout << "c = a -> " << c << endl; c += a; cout << "c += a -> " << c << endl; c -= a; cout << "c -= a -> " << c << endl; c *= a; cout << "c *= a -> " << c << endl; c /= a; cout << "c /= a -> " << c << endl; c = 200; c %= a; cout << "c %= a -> " << c << endl; c <<= 2; cout << "c <<= 2 -> " << c << endl; c >>= 2; cout << "c >>= 2 -> " << c << endl; c &= 2; cout << "c &= 2 -> " << c << endl; c ^= 2; cout << "c ^= 2 -> " << c << endl; c |= 2; cout << "c |= 2 -> " << c << endl; return 0; } ``` 輸出結果: ``` 初始值 a = 21 c = a -> 21 c += a -> 42 c -= a -> 21 c *= a -> 441 c /= a -> 21 c %= a -> 11 c <<= 2 -> 44 c >>= 2 -> 11 c &= 2 -> 2 c ^= 2 -> 0 c |= 2 -> 2 ``` 總結 --- 有關於其他運算子的相關名詞解釋可看這篇(作者推薦):[運算子的優先權 - HackMD](https://hackmd.io/@ndhu-programming-2021/HJAkAf8AF#%E5%89%8D%E8%A8%80) ***邏輯運算子(Logical Operator):*** | 運算子 | 描述 | | -------- | -------- | | && | 邏輯 AND 運算子,如果兩個運算元都是 true,則條件為 true。 | | || | 邏輯 OR 運算子,如果兩個運算元中其中一個是 true,則條件為 true。 | | ! | 邏輯 NOT 運算子,主要用來反轉邏輯狀態的運算子,像是 (A&&B) 若為 true,則 !(A&&B) 為 false。 | ![image](https://hackmd.io/_uploads/SJddXTuVR.png) Image Source:[Advanced Search Techni... | Klingemann Library LibGuides](https://libguides.berlin-international.de/books/how-to-search/page/advanced-search-techniques) 邏輯運算子主要應用條件判斷上面,邏輯運算子通常用於布林運算式當中,如:true && false。 ***位元運算子(Bitwise Operator):*** C++ 當中,提供了 AND(&)、OR(|)、NOT(!)、XOR(^)、補數(~)complement 等位元運算子。 * AND 表示兩真值成立才得以成立,也就是運算元都必須是 1。 * OR 表示兩真值其中之一個成立就可以成立,也就是所有運算元當中其中一個是 1 即可成立。 * NOT 表示反轉邏輯,如 AND 運算過後的結果是 1,則使用 ! NOT 運算子會讓它變成 0。 * XOR 表示兩真值其中之一個成立就可以成立,***且必須沒有交集***,交集意思就是 1、1,0、0,兩個運算元是有相同的值。 補數(~)complement 將二進位的 0 轉換成 1,1 轉換成 0。 ***指定運算子(Assignment Operator):*** 指定運算子就是用於簡化變數指定流程的一種運算子。 | 運算子 | 描述 | 實例 | | -------- | -------- | -------- | | = | 指定運算子。 | c = a + b,將 a + b 運算過後指定給 C。 | | += | 加和指定運算子。 | c += a 等於 c = c + a。 | | -= | 減和指定運算子。 | c -= a 等於 c = c - a。 | | *= | 乘和指定運算子。 | c *= a 等於 c = c * a。 | | /= | 除和指定運算子 | c /= a 等於 c = c / a。 | | %= | 取模和指定運算子。 | c %= a 等於 c = c % a。 | | <<= | 左移和指定運算子。 | c <<= a 等於 c = c << a。 | | >>= | 右移和指定運算子。 | c >>= a 等於 c = c >> a。 | | &= | AND位元運算子和指定運算子。 | c &= a 等於 c = c & a。 | | ^= | XOR位元運算子和指定運算子。 | c ^= a 等於 c = c ^ a。 | | |= | OR位元運算子和指定運算子。 | c |= a 等於 c = c | a。 | 今日已學 C++ 運算子當中的: * 邏輯運算子 * 位元運算子 * 指定運算子 參考資料 --- [快速搞懂位元運算子的 AND. 位元運算子是用於處理二進位數字的運算符號。這些運算符號通常用於程式語言中,並對二… | by Roan | Medium](https://medium.com/@roan6903/%E5%BF%AB%E9%80%9F%E6%90%9E%E6%87%82-javascript-%E4%BD%8D%E5%85%83%E9%81%8B%E7%AE%97%E5%AD%90%E7%9A%84-and-fdf60531473f) [邏輯運算、位元運算](https://openhome.cc/Gossip/CppGossip/LogicalBitwise.html) [C++ 运算符 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-operators.html)