⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logicalbitwise.html

📁 关于 C++ 的历史无须我来介绍了
💻 HTML
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

  
  <link rel="stylesheet" href="css/stdlayout.css" type="text/css">

  
  <link rel="stylesheet" href="css/print.css" type="text/css">

  
  <meta content="text/html; charset=gb2312" http-equiv="content-type">

  
  <title>逻辑运算、位元运算</title>
</head>


<body>

<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>

<h1><a href="CppGossip.html">C++ Gossip:&nbsp;逻辑运算、位元运算</a></h1>

<br>

在逻辑上有所谓的“且”、“或”与“反”运算,在C++中也提供这几个基本逻辑运算所需的“逻辑运算子”(Logical
operator),分别为“且”(&amp;&amp;)、“或”(||)及“反相”(!)三个运算子。 <br>

<br>

来看看下面这个程式会输出什么? <br>

<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int
num = 75; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cout
&lt;&lt;&nbsp; (num &gt; 70 &amp;&amp; num
&lt; 80) &lt;&lt; endl; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cout
&lt;&lt; (num &gt; 80 || num &lt; 75) &lt;&lt;
endl; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cout
&lt;&lt; !(num &gt; 80 || num &lt; 75) &lt;&lt;
endl;</span><br>

</div>

<br>

三段程式分别会输出1、0与1,也就是分别表示true、false与true三种状况。 <br>

<br>

&amp;&amp;运算中,如果左边的式子已经被评断为false,则可立即判断整个式子为false,因而右边的式子就不会再评断;
|| 运算中如果左边的式子已经被评断为true,则可以判断整个式子为true,因而右边的式子就不会再评断。<br>

<br>

接下来看看“位元运算子”(Bitwise
operator),数位设计上有AND、OR、NOT、XOR与补数等运算,在C++中提供这些运算的就是位元运算子,它们的对应分别是AND
(&amp;)、OR(|)、NOT(!)、XOR(^)与补数(~)。 <br>

<br>

如果您不会基本的位元运算,这边可以提供一个程式来显示各个运算的结果: <br>

<br>

<pre>#include &lt;iostream&gt;<br>using namespace std;<br> <br>int main() { <br>    cout &lt;&lt; "AND运算:" &lt;&lt; endl; <br>    cout &lt;&lt; "0 AND 0\t\t" &lt;&lt; (0 &amp; 0) &lt;&lt; endl; <br>    cout &lt;&lt; "0 AND 1\t\t" &lt;&lt; (0 &amp; 1) &lt;&lt; endl; <br>    cout &lt;&lt; "1 AND 0\t\t" &lt;&lt; (1 &amp; 0) &lt;&lt; endl; <br>    cout &lt;&lt; "1 AND 1\t\t" &lt;&lt; (1 &amp; 1) &lt;&lt; endl; <br><br>    cout &lt;&lt; "OR运算:" &lt;&lt; endl; <br>    cout &lt;&lt; "0 OR 0\t\t" &lt;&lt; (0 | 0) &lt;&lt; endl; <br>    cout &lt;&lt; "0 OR 1\t\t" &lt;&lt; (0 | 1) &lt;&lt; endl; <br>    cout &lt;&lt; "1 OR 0\t\t" &lt;&lt; (1 | 0) &lt;&lt; endl; <br>    cout &lt;&lt; "1 OR 1\t\t" &lt;&lt; (1 | 1) &lt;&lt; endl; <br><br>    cout &lt;&lt; "XOR运算:" &lt;&lt; endl; <br>    cout &lt;&lt; "0 XOR 0\t\t" &lt;&lt; (0 ^ 0) &lt;&lt; endl; <br>    cout &lt;&lt; "0 XOR 1\t\t" &lt;&lt; (0 ^ 1) &lt;&lt; endl; <br>    cout &lt;&lt; "1 XOR 0\t\t" &lt;&lt; (1 ^ 0) &lt;&lt; endl; <br>    cout &lt;&lt; "1 XOR 1\t\t" &lt;&lt; (1 ^ 1) &lt;&lt; endl; <br><br>    cout &lt;&lt; "NOT运算:" &lt;&lt; endl; <br>    cout &lt;&lt; "NOT 0\t\t" &lt;&lt; (!0) &lt;&lt; endl; <br>    cout &lt;&lt; "NOT 1\t\t" &lt;&lt; (!1) &lt;&lt; endl; <br> <br>    return 0;<br>}</pre>

<br>

执行结果如下: <br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">AND运算: <br>

0 AND 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 <br>

0 AND 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 <br>

1 AND 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 <br>

1 AND 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 <br>

OR运算: <br>

0 OR 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 <br>

0 OR 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 <br>

1 OR 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 <br>

1 OR 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 <br>

XOR运算: <br>

0 XOR 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 <br>

0 XOR 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 <br>

1 XOR 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 <br>

1 XOR 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 <br>

NOT运算: <br>

NOT 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 <br>

NOT 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<br>

      </span></small></td>

    </tr>

  
  </tbody>
</table>

<br>

C++中的位元运算是逐位元运算的,例如10010001与01000001作AND运算,是一个一个位元对应运算,答案就是00000001;而补数运
算是将所有的位元0变1,1变0,例如00000001经补数运算就会变为11111110,例如下面这个程式所示: <br>

<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">char num = 255; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cout
&lt;&lt;&nbsp;static_cast&lt;int&gt;(~num);</span><br>

</div>

<br>

这段程式会在主控台显示0,char使用一个位元组,若用于储存正整数最大可储存255的值,255的二进位表示法为11111111,经补数运算就是
00000000,也就是0。 <br>

<br>

要注意的是,逻辑运算子与位元运算子也是很常被混淆的,像是&amp;&amp;为逻辑运算,而&amp;为位元运算,||为逻辑运算,而|为位元运算,
初学时可得多注意。 <br>

<br>

位元运算对初学者来说的确较不常用,但如果用的洽当的话,可以增进不少程式效率,例如下面这个程式可以判断使用者的输入是否为奇数:<br>

<br>

<pre>#include &lt;iostream&gt;<br>using namespace std;<br><br>int main() { <br>    int input = 0; <br><br>    cout &lt;&lt; "输入正整数:"; <br>    cin &gt;&gt; input; <br>    cout &lt;&lt; "输入为奇数?" <br>         &lt;&lt; (input&amp;1 ? 'Y' : 'N') <br>         &lt;&lt; endl;  <br>    <br>    return 0;<br>}</pre>

<br>

执行结果如下: <br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">输入正整数:5<br>

输入为奇数?Y<br>

      </span></small></td>

    </tr>

  
  </tbody>
</table>

<br>

这个程式得以运算的原理是,奇数的数值若以二进位来表示,其最右边的位元必为1,而偶数最右边的位元必为0,所以您使用1来与输入的值作AND运算,由于
1除了最右边的位元为1之外,其它位元都会是0,与输入数值AND运算的结果,只会留下最右边位元为0或为的结果,其它部份都被0
AND运算遮掉了,这就是所谓“位元遮罩”,例如:<br>

<table style="text-align: left; width: 25%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000100</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>4</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000001</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>1</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000000</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>判断为偶数</small></td>

    </tr>

  
  </tbody>
</table>

<br>

<br>

<table style="text-align: left; width: 25%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000011</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>3</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000001</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>1</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000001</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>判断为奇数</small></td>

    </tr>

  
  </tbody>
</table>

<br>

<br>

XOR的运算较不常见,这边举个简单的XOR字元加密例子,先看看程式:<br>

<br>

<pre>#include &lt;iostream&gt;<br>using namespace std;<br>                                                                                                                                                          <br>int main() { <br>    char ch = 'A'; <br><br>    cout &lt;&lt; "before encoding:" &lt;&lt; ch <br>         &lt;&lt; endl; <br><br>    ch = ch^0x7; <br>    cout &lt;&lt; "after encoding:" &lt;&lt; ch <br>         &lt;&lt; endl; <br><br>    ch = ch^0x7; <br>    cout &lt;&lt; "decoding:" &lt;&lt; ch <br>         &lt;&lt; endl; <br>    <br>    return 0;<br>}</pre>

<br>

执行结果如下: <br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">before encoding:A<br>

after encoding:F<br>

decoding:A<br>

      </span></small></td>

    </tr>

  
  </tbody>
</table>

<br>

0x7是C++中整数的16进位写法,其实就是10进位的7,将位元与1作XOR的作用其实就是位元反转,0x7的最右边三个位元为1,所以其实就是反转
ch的最后两个字元,如下所示:<br>

<table style="text-align: left; width: 273px;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>01000001</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace; width: 191px;"><small>65(对应
ASCII的'A')</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000111</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace; width: 191px;"><small>0x7</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>01000110</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace; width: 191px;"><small>70(对应
ASCII中的'F')</small></td>

    </tr>

  
  </tbody>
</table>

<br>

同样的,这个简单的XOR字元加密,要解密也只要再进行相同的位元反转就可以了。 <br>

<br>

要注意的是,虽然在说明时都只取8个位元来说明,但实际的位元在运算时,需依资料型态所占的记忆体长度而定,例如在使用int型态的0作运算时,要考虑的
是32个位元,而不是只有8个位元,因为int占有4个位元组。 <br>

<br>

在位元运算上,C++还有左移(&lt;&lt;)与右移(&gt;&gt;)两个运算子,注意在这边与cout与cin所使用的&lt;&lt;与
&gt;&gt;作用是不一样的;左移运算子会将所有的位元往左移指定的位数,左边被挤出去的位元会被丢弃,而右边会补上0;右移运算则是相反,会将所有
的位元往右移指定的位数,右边被挤出去的位元会被丢弃,至于左边位元补0或补1则不一定,视系统而定。 <br>

<br>

您可以使用左移运算来作简单的2次方运算示范,如下所示: <br>

<br>

<pre>#include &lt;iostream&gt;<br>using namespace std;<br>                                                                                                                                                          <br>int main() { <br>    int num = 1; <br><br>    cout &lt;&lt; "2的0次:" &lt;&lt; num<br>         &lt;&lt; endl; <br><br>    num = num &lt;&lt; 1; <br>    cout &lt;&lt; "2的1次:" &lt;&lt; num<br>         &lt;&lt; endl;     <br><br>    num = num &lt;&lt; 1; <br>    cout &lt;&lt; "2的2次:" &lt;&lt; num<br>         &lt;&lt; endl;     <br><br>    num = num &lt;&lt; 1; <br>    cout &lt;&lt; "2的3次:" &lt;&lt; num <br>         &lt;&lt; endl; <br>    <br>    return 0;<br>}</pre>

<br>

执行结果如下: <br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">2的0次:1<br>

2的1次:2<br>

2的2次:4<br>

2的3次:8<br>

      </span></small></td>

    </tr>

  
  </tbody>
</table>

<br>

实际来左移看看就知道为何可以如此运算了: <br>

<table style="text-align: left; width: 25%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000001</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>1</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000010</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>2</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00000100</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>4</small></td>

    </tr>

    <tr>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>00001000</small></td>

      <td style="font-weight: bold; font-family: Courier New,Courier,monospace;"><small>8</small></td>

    </tr>

  
  </tbody>
</table>

<br>

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -