計算機概論:C/C++程式設計

 

 

2章、C++程式基本元素

 

 


授課教師:陳慶瀚

WWW : http://www.miat.ee.isu.edu.tw/cpp

E-mail : pierre@isu.edu.tw   

 

2.8 位元運算(bitwise operation)

一個位元(bit)是所有數位資訊的最小單位,一個位元值只有兩種可能值:01(有時在不同的情況,我們也會將一個位元值表示為on/offtrue/false)。位元的處理是程式對電腦所能做的最低階的控制。

8個位元構成一個位元組(byte),在C/C++語言中,我們使用char(字元)資料型別來表示byte。例如一個字元的變數值可能包含位元如下: 01101100

如果用16進位(hexadecimal)來表示上述字元值,則寫成0x6CC/C++ 使用一個前置號“0x”來表示其後的數值是16進位。每一個16進位數值需要4 bits,因此上例的01101100就分成(0110)2=616, (1100)2=C16 ,結合起來就是0x6C。表2-1 是二進位與十六進位轉換的對照表

2-1二進位與十六進位轉換的對照表

Hex

Binary

Hex

Binary

0

0000

8

1000

1

0001

9

1001

2

0010

A

1010

3

0011

B

1011

4

0100

C

1100

5

0101

D

1101

6

0110

E

1110

7

0111

F

1111


位元運算子(bitwise operator)可以讓程式設計者直接操作個別的位元。 例如對於16 bits所構成的整數(int)變數,使用位元運算子可以直接處理這16個位元的任意一個獨立位元值,相反的,其他的算數運算子(如加法運算子)僅能夠把這16個位元視為一個16-bit 的數值,而不能夠分開處理。  

位元運算子主要功能在於對單一位元執行設定(1)、清除(0)、邏輯運算、移位等處理。這些位元運算子可以應用在所有的整數變數(int)和字元變數(char)。表2-2列出這些位元運算子和它們的功能。

2-2位元運算子和它們的功能

&

Bitwise AND

兩個位元進行位元AND運算

|

Bitwise OR

兩個位元進行位元OR運算

^

Bitwise exclusive OR 

兩個位元進行位元XOR運算

~

Complement

一個位元的位元NOT運算

<<

Shift left 

位元向左移位

>>

Shift right

位元向右移位

AND位元運算子(&) 

AND位元運算子比較兩個位元,如果兩個位元都是1,則運算結果為1,否結為0。當兩個8-bit 變數(char)執行AND運算, 則兩個變數的每一個位元都獨立的執行AND運算。

/*----------------------------------------------------*/

//                  範例程式2-8

//                  AND位元運算

//                  陳慶瀚,2001

/*----------------------------------------------------*/

#include <iostream.h>

void main()

{

   int a, b, c;

   a = 3; // 0011

   b = 7; // 1111

   c = a & b; // (0011) AND (1111) = (0011)

   cout <<a<<" AND(&) "<<b<< " = " <<c<<endl;

}

OR位元運算子 (|) 

OR位元運算子比較兩個位元,只要其中有一個位元為1或兩個位元都是1,則運算結果為1,否則為0  

/*----------------------------------------------------*/

//                  範例程式2-8

//                   OR位元運算

//                  陳慶瀚,2001

/*----------------------------------------------------*/

#include <iostream.h>

void main()

{

   char a, b, c;

   a = 0x47; // 01000111 

   b = 0x53; // 01010011 

   c = a | b; // (01000111) AND (01010011) = (01010111)

   cout <<int(a)<<" OR(|) "<<int(b)<< " = " <<int(c)<<endl;

}

NOT位元運算(~)

不像AND,OR位元運算子都是作用在兩個運算元(operands)上,NOT位元運算子只作用在單一運算元,它會將單一位元值反轉,也就是0變成11變成。

/*----------------------------------------------------*/

//                  範例程式2-9

//                 NOT位元運算

//                  陳慶瀚,2001

/*----------------------------------------------------*/

#include <iostream.h>

void main()

{

   unsigned char a,b;

   a = 255; // 11111111 

   b=~a;     // 00000000

   cout <<"a = "<<int(a)<<", NOT(a)= "<<int(b)<<endl;

}

位元左移和右移運算子(<<, >>) 

位元左移運算子<<將變數值的每一個位元向左移,程式設計者可已指定要左移幾個位元任何位元只要移出最高位元後就自然消失,至於最低位元左移後出缺的位元就補0。使用位元左移運算子的語法如下:

變數<<左移位元數;

/*----------------------------------------------------*/

//                  範例程式2-10

//                  NOT位元運算

//                  陳慶瀚,2001

/*----------------------------------------------------*/

#include <iostream.h>

void main()

{

   unsigned char c;      //宣告一個資料型別圍char的正整數

   c=0x1C;                 //1C16(= 2810 = 000111002)指定給變數c

   cout<<int(c)<<endl;  //c轉為10進位輸出(2810)

   c = c << 1;            //c左移一個位元(左移後為00111000)

   cout<<int(c)<<endl;  //c轉為10進位輸出(5610)

   c = c >> 2;            //再將c右移2個位元(右移後為00000111)

   cout<<int(c)<<endl;  //c轉為10進位輸出(1410)

}

我們注意到如果將一個整數變數向左移一個位元,其變數值變成原值(28)2倍數(56),如果我們把第7

   c = c << 1;  

改成

   c = c << 2;  

結果是原值乘以4。如果左移3,4,5...,N個位元,就相當於變數值乘以8,16,32,...,2N的倍數值。

至於位元右移運算子>>的功能是類似的,如果我們右移1,2,3,...,N個位元,就相當將原變數值除以2,4,8,...,2N

所以位元左移和右移運算子可以取代一些特定的2N乘法和除法運算,對於一些需要高執行效率的應用程式來說,這是非常有用的,因為位元左移和右移運算的速度遠快於執行整數的乘法和除法運算。所以,如果有一行程式碼

i  = j * 8; 

基於執行效率上的考量,可以改成

i = j << 3;     //  i = j*23

這種寫法可加快程式的速度,但不可避免的會降低原始碼的可閱讀性,因為一般人閱讀上述原始碼並不容易直覺地判斷這是一個乘8的運算,因此在掌握或修改程式上就會較困難。所以如果程式執行效率如果不是最重要考量的話,還是寫成i=j*8是較具親和性的做法。


 

計算機概論:C/C++程式設計

義守大學電機系 陳慶瀚  
2001.10.02