久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

第十二章位運(yùn)算

 running_to_you 2017-05-12

第十二章  運(yùn)

12.1位運(yùn)算及其應(yīng)用

12.1.1位運(yùn)算的分類:

  位邏輯運(yùn)算,、位移運(yùn)算兩種

12.1.2位邏輯運(yùn)算[]

  &      |       ^        ~

【位邏輯運(yùn)算的特點(diǎn)】

 ▲只作用于整型,、字符型數(shù)據(jù);

 ▲作用于整型,、字符型數(shù)據(jù)的每個(gè)二進(jìn)制位,,不是數(shù)的整體

 ▲而一般邏輯運(yùn)算是作用數(shù)的整體,不是數(shù)的每個(gè)二進(jìn)制位,。運(yùn)算結(jié)果是二進(jìn)制數(shù),。

1、按位與運(yùn)算符(&):

1)運(yùn)算規(guī)則:

0&0=0       1&0=0       0&1=0       1&1=1 

▲只要對應(yīng)位上的值均為1則該位上的結(jié)果值為1

2)特殊作用,。

①將一個(gè)存儲單元各位清0

②取某個(gè)數(shù)中的某些位,。  

▲方法:將本數(shù)與某個(gè)特定數(shù)按位與運(yùn)算即可。

2,、按位或運(yùn)算符(|

1)運(yùn)算規(guī)則:

0|0=0        1|0=1         0|1=1          1|1=1

▲只要對應(yīng)位上的值其中一個(gè)為1則該位上的結(jié)果值為1

2)特殊作用,。

①常用于將一個(gè)數(shù)的某些特定位置為1

▲方法:將本數(shù)與某個(gè)特定數(shù)按位或運(yùn)算即可。

3,、按位異或運(yùn)算符(^

1)運(yùn)算規(guī)則:

0^0=0    1^0=1     0^1=1       1^1=0

▲只要對應(yīng)位上的值互不相同則該位上的結(jié)果值為1

2)特殊作用[p300],。

    ①使某些特定的翻轉(zhuǎn)

②任何數(shù)與0相異或結(jié)果保留原數(shù)本身

③交換兩個(gè)變量的值不用中間變量。

    a=a^b    b=b^a   a=a^b

▲注意給變量賦值的先后順序,。

4,、按位異求反運(yùn)算符(~)

1)運(yùn)算規(guī)則:

~0=1       ~1=0

▲對每個(gè)上的值按位求反:1變?yōu)?/span>00變?yōu)?/span>1,。

▲注意以上位邏輯運(yùn)算的優(yōu)先級別,。

▲注意:~運(yùn)算符比算術(shù)運(yùn)算、關(guān)系運(yùn)算,、邏輯運(yùn)算和其它運(yùn)算的優(yōu)先級別都高,。

12.1.3位移運(yùn)算[]     <<            >>

1、左位移運(yùn)算符(<<):

· 1)運(yùn)算規(guī)則:  a=a<<n  a中所有位向左移動n位,。

· 2)運(yùn)算的作用:相當(dāng)于乘法運(yùn)算,。左移一位相當(dāng)于乘以2

▲高位[左邊位]左移后溢出被舍棄,,不起作用,。低位補(bǔ)以0

位移運(yùn)算及其作用[右位移運(yùn)算(>>]

1)運(yùn)算規(guī)則:  a=a>>n  a中所有位向右移動n位,。

2)運(yùn)算的作用:相當(dāng)于除法運(yùn)算,。右移一位相當(dāng)于除以2

【注意】注意數(shù)的符號問題[即正負(fù)的問題]

▲對于無符號數(shù)[正數(shù)]右移時(shí)高位補(bǔ)以0,。

▲對于有符號數(shù),,高位為0[正數(shù)]右移時(shí)高位補(bǔ)以0

▲對于有符號數(shù),,高位為1[負(fù)數(shù)]時(shí):

    ①右移時(shí)高位補(bǔ)以0,,稱之為“邏輯位移”。

    ②右移時(shí)高位補(bǔ)以1,,稱之為“算術(shù)位移”,。

TC采用“算術(shù)位移”,,高位補(bǔ)以1

左位移運(yùn)算符(<<

12.1.4 位運(yùn)算賦值運(yùn)算符

位運(yùn)算符與賦值運(yùn)算符可以組成復(fù)合賦值運(yùn)算符如:&=, |=, >>=, <<=, =

例如,a & = b相當(dāng)于 a = a & b,。a << =2相當(dāng)于:a = a << 2,。

12.1.5 不同長度的數(shù)據(jù)進(jìn)行位運(yùn)算

如果兩個(gè)數(shù)據(jù)長度不同(例如long型和int)進(jìn)行位運(yùn)算時(shí)(a & b,along,bint),系統(tǒng)會將二者按右端對齊。如果b為正數(shù),則左側(cè)16位補(bǔ)滿0,。若b為負(fù)數(shù),左端應(yīng)補(bǔ)滿1,。如果b為無符號整數(shù)型,則左側(cè)添滿0

12.2 位運(yùn)算舉例

12.1取一個(gè)整數(shù)a從右端開始的47位,。

可以這樣考慮:

先使a右移4位,。見圖12.3。圖12.3(a)是未右移時(shí)的情況,(b)圖是右移4位后的情況,。目的是使要

取出的那幾位移到最右端,。

11

右移到右端可以用下面方法實(shí)現(xiàn):

a >> 4

設(shè)置一個(gè)低4位全為1,其余全為0的數(shù)??捎孟旅娣椒▽?shí)現(xiàn):

~ ( ~ 0 << 4 )

0的全部二進(jìn)制為全1,,左移4位,這樣右端低4位為0,。見下面所示:

0:0000000000

~0: 1111111111

~0<<4:1111110000

~(~0<<4):0000001111

將上面二者進(jìn)行&運(yùn)算,。即

(a >> 4)  & ~ ( ~ 0 << 4 )

 根據(jù)上一節(jié)介紹的方法,與低4位為1的數(shù)進(jìn)行&運(yùn)算,,就能將這4位保留下來,。

  程序如下:

main()

{

unsigned ab,,c,,d

    scanf("%o",,&a),;

    b=a>>4

    c=(0<<4),;

    d=b&c,;

    printf("%o %d\n%o,, %d\n",,aa,,d,,d)

}

運(yùn)行情況如下:

331

331,, 217(a的值)

15,, 13  (d的值)

輸入a的值為八進(jìn)制數(shù)331,, 即十進(jìn)制數(shù)217 其二進(jìn)制形式為11011001,。經(jīng)運(yùn)算最后得到的d00001101,,即八進(jìn)制數(shù)15,十進(jìn)制數(shù)13,。

11

可以任意指定從右面第m位開始取其右面n位。只需將程序中的“b=a>>4”改成“b=a>>(m-n+1)”以及將“c=(0<<4)”改成“c=(0<<n)”即可,。

12.2循環(huán)移位,。要求將a進(jìn)行右循環(huán)移位。見圖12.4,。圖12.4表示將a右循環(huán)移n位,。即將a中原來左面(16-n)位右移n位,原來右端n位移到最左面n位,。今假設(shè)用兩個(gè)字節(jié)存放一個(gè)整數(shù),。為實(shí)現(xiàn)以上目的可以用以下步驟:

a的右端n位先放到b中的高n位中??梢杂孟旅嬲Z句實(shí)現(xiàn):b=a<<(16-n),;

a右移n位,其左面高位n位補(bǔ)0,??梢杂孟旅嬲Z句實(shí)現(xiàn):

c=a>>n

cb進(jìn)行按位或運(yùn)算,。即

c=c|b,;

程序如下:

main( )

{

unsigned ab,,c,;

    int n

    scanf("a=%o,,n=%d",,&a&n),;

    b=a<<(16-n),;

c=a>>n

    c=c|b,;

    printf("%o\n%o",,ac),;

}

運(yùn)行情況如下:

a=157653,,n=3

0     157653

     75765

運(yùn)行開始時(shí)輸入八進(jìn)制數(shù)157653,,即二進(jìn)制數(shù)1101111110101011,循環(huán)右移3位后得二進(jìn)制數(shù)0111101111110101,,即八進(jìn)制數(shù)75765,。同樣可以左循環(huán)位移。

12.3 位段

以前曾介紹過對內(nèi)存中信息的存取一般以字節(jié)為單位,。實(shí)際上,,有時(shí)存儲一個(gè)信息不必用一個(gè)或多個(gè)字節(jié),例如,,“真”或“假”用01表示,,只需1位即可。在計(jì)算機(jī)用于過程控制,、參數(shù)檢測或數(shù)據(jù)通信領(lǐng)域時(shí),,控制信息往往只占一個(gè)字節(jié)中的一個(gè)或幾個(gè)二進(jìn)位,常常在一個(gè)字節(jié)中放幾個(gè)信息,。那么,,怎樣向一個(gè)字節(jié)中的一個(gè)或幾個(gè)二進(jìn)位賦值和改變它的值呢?可以用以下兩種方法:

(1) 可以人為地在一個(gè)字節(jié)data中設(shè)幾項(xiàng),。例如:a,、bc,、d分別占2位,、6位、4位,、4(見圖12.5),。如果想將c的值變?yōu)?/span>12(設(shè)c原來為0),可以這樣:

11

12.5

將數(shù)12左移4位,,使1100成為右面起第47位,。

data與“12<<4 進(jìn)行“按位或” 運(yùn)算,即可使c的值變成12,。

如果c的原值不為0,,應(yīng)先使之為0??梢杂孟旅娣椒ǎ?/span>

data=data & 0177417

0177417的二進(jìn)制表示為

11  11111 1  0000  1111

a     b        c     d

也就是使第47位全為0,其他位全為1,。它與data進(jìn)行 &運(yùn)算,使第47位為0,其余各位保留data的原狀。這個(gè)177417稱為“屏蔽字”,即把c以外的信息屏蔽起來,不受影響,只使c改變?yōu)?/span>0,。 但要找出和記住177417這個(gè)數(shù)比較麻煩,。可以用data=data & ~ ( 15 << 4 );15c的最大值,c共占4,最大值為11111515<<4是將1111移到47位,。 再取反,就使47位變成0,其余位全是1,。即

15:0000000000001111

15 << 4:0000000011110000

~ ( 15 << 4 ):1111111100001111

這樣可以實(shí)現(xiàn)對c0,而不必計(jì)算屏蔽碼。

將上面幾步結(jié)合起來,可以得到

data=data & ~ ( 15 << 4 )| ( n & 15 ) << 4;

          賦予47位為0

n為應(yīng)賦給c的值(例如12)\. n & 15的作用是只取n的右端4位的值,其余各位置0,即把n放到最后4位上,( n & 15 ) << 4, 就是將n置在47位上,。見下面:

data & ~(15<<4): 11011011|0000|1010

   (n & 15)<<4: 00000000|1100|0000

  (按位或運(yùn)算)    11011011|1100|1010

可見,data的其他位保留原狀未改變,而第47位改變?yōu)?/span>12(1100)了,。

但是用以上辦法給一個(gè)字節(jié)中某幾位賦值太麻煩了??梢杂孟旅娼榻B的位段結(jié)構(gòu)體的方法,。 

(2) 位段

C語言允許在一個(gè)結(jié)構(gòu)體中以位為單位來指定其成員所占內(nèi)存長度,這種以位為單位的成員稱為“位段”或稱“位域” ( bit field) ,。利用位段能夠用較少的位數(shù)存儲數(shù)據(jù),。

例如:

 struct packed-data

 {

   unsigned a2

       unsigned b6,;

       unsigned c4

       unsigned d4,;

       int i,;

 }data

見圖12.6,。其中a,、bc,、d分別占2位,、6位、4位,、4位,。i為整型。共占4個(gè)字節(jié),。

11

12.6

也可以使各個(gè)位段不恰好占滿一個(gè)字節(jié),。如:

 struct packed-data

 {

   unsigned a2

       unsigned b3,;

       unsigned c4,;

       int i

 },;

 struct packed-data data,;

見圖12.7。其中a,、b,、c共占9位,占1個(gè)字節(jié)多,不到2個(gè)字節(jié),。它的后面為int型,,占2個(gè)字節(jié)。在a,、b,、c之后7位空間閑置不用,i從另一字節(jié)開頭起存放,。

11

12.7

11

12.8

注意,,在存儲單元中位段的空間分配方向,因機(jī)器而異,。在微機(jī)使用的C系統(tǒng)中,,一般是由右到左進(jìn)行分配的,如圖12.8,。但用戶可以不必過問這種細(xì)節(jié),。對位段中的數(shù)據(jù)引用的方法。如:

dataa=2,;

datab=7,;

datac=9

注意位段允許的最大值范圍,。如果寫dataa=8,;

就錯了。因?yàn)?/span>data.a只占2位,,最大值為3,。在此情況下,自動取賦予它的數(shù)的低位,。例如,,8的二進(jìn)制數(shù)形式為1000,而dataa只有2位,,取1000的低2位,,故dataa得值0

關(guān)于位段的定義和引用,,有幾點(diǎn)要說明:

(1) 位段成員的類型必須指定為unsignedint類型,。

(2) 若某一位段要從另一個(gè)字開始存放??梢杂靡韵滦问蕉x:

unsigned a1,;

unsigned b2     一個(gè)存儲單元      

unsigned0,;

unsigned c3,;   (另一存儲單元)

本來a,、bc應(yīng)連續(xù)存放在一個(gè)存儲單元()中,,由于用了長度為0的位段,,其作用是使下一個(gè)位段從下一個(gè)存儲單元開始存放。因此,,現(xiàn)在只將a,、b存儲在一個(gè)存儲單元中,c另存放在下一個(gè)單元,。(上述“存儲單元”可能是一個(gè)字節(jié),,可能是29字節(jié),視不同的編譯系統(tǒng)而異,。)

(3) 一個(gè)位段必須存儲在同一存儲單元中,,不能跨兩個(gè)單元。如果第一個(gè)單元空間不能容納下一個(gè)位段,,則該空間不用,,而從下一個(gè)單元起存放該位段。(4) 可以定義無名字段,。如:

unsigned a1,;

unsigned   2(這兩位空間不用)

unsigned  b3,;

unsigned  c4

 

見圖12.9,。在a后面的是無名位段,,該空間不用。

11

12.9

(5) 位段的長度不能大于存儲單元的長度,,也不能定義位段數(shù)組,。

(6) 位段可以用整型格式符輸出。如:

  printf("%d,,%d,,%d"dataa,,datab,,datac)

當(dāng)然,,也可以用%u,、%o%x等格式符輸出,。

(7) 位段可以在數(shù)值表達(dá)式中引用,,它會被系統(tǒng)自動地轉(zhuǎn)換成整型數(shù)。如:dataa+5/datab是合法的。

 

 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多