《第11章 位運算》由會員分享,可在線閱讀,更多相關(guān)《第11章 位運算(30頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、,單擊此處編輯母版標題樣式,單擊此處編輯母版文本樣式,第二級,第三級,第四級,第五級,*,第10章 位運算,11.1 位運算符,11.2 位段,11.3應用舉例,11.1 位運算符,當兩個運算對象的位數(shù)不同時,系統(tǒng)將自動進行如下處理:,先將兩個運算數(shù)右端對齊。,再將位數(shù)不足的一個運算對象向高位擴充,即:無符號數(shù)和正整數(shù)左端用0補齊;負數(shù)左端用1補齊;然后對位數(shù)相等的這兩個數(shù)按位進行運算。,“按位與”運算(&),“按位與”運算是將參加運算的兩操作對象,按對應的二進制位分別進行“邏輯與”運算。,運算規(guī)則為:只有兩個相應位都為1時,該位的運算結(jié)果才為1;兩個相應位的值相異或均為0時,該位的運算結(jié)果為
2、0。,11.1 位運算符,【例11.1】求表達式12&10的值。,main(),char x=12,y=10;,printf,(“%d,%dn”,x,y);,x=x,printf,(“%d,%dn”,x,y);,輸出結(jié)果為:,12,10,8,10,11.1 位運算符,按位與運算用途:,清零:若想將某個存儲單元清零,只需將這個存儲單元的值與零進行“與”運算。,【例11.2】分析下面程序結(jié)果,main(),char,ch,=46;,printf,(%d n,ch,);,ch,=,ch,printf,(%d n,ch,);,輸出結(jié)果為:46,0,11.1 位運算符,獲取指定位:如果要想獲取某數(shù)據(jù),X
3、,的指定位,則可以用一個數(shù)與,X,進行“與”運算,此數(shù)在與指定位相同的位上的值為1,其余各位為0。,【例11.3】從鍵盤輸入一個整數(shù),判斷此數(shù)是否能被2整除。,#,include,main(),int,x;,printf,(Please input a number:);,scanf,(%d,if(x&0 x01)=0)/*,通過與運算,只保留該數(shù)的最低位,然后判斷其是否為0*/,printf,(n%d can be divided by 2 exactly!,x);/*,最低位為0,該數(shù)能被2整除*/,else,printf,(n%d cant be divided by 2 exactly
4、!,x);/*,最低位為1,不能被2整除*/,11.1 位運算符,“按位或”運算(|),按位或運算是將參加運算的兩操作對象,按對應的二進制位分別進行“邏輯或”運算。,運算規(guī)則為:只有兩個相應位都為0時,該位的運算結(jié)果才為0,其它情況下,結(jié)果全為1。,【例11.4】求表達式12|10的值。,main(),char x=12,y=10;,printf,(“%d,%dn”,x,y);,x=x|y;,printf,(“%d,%dn”,x,y);,輸出結(jié)果為:,12,10,14,10,11.1 位運算符,用途:按位“或”經(jīng)常用來對一個數(shù)據(jù)的某些位置1。,【例11.5】把整數(shù),x(8,位)的低4位置1,高
5、4位不變。,main(),char x=67;,printf,(“%dn”,x);,x=x|15;,printf,(“%dn”,x);,輸出結(jié)果為:,67,79,11.1 位運算符,“按位異或”運算(),按位或運算是將參加運算的兩操作對象,按對應的二進制位分別進行“按位異或”運算。,運算規(guī)則為“按位異或”的應用:參加運算的兩個運算量,如果兩個相對應位上的值不同,則該位的結(jié)果為1;如果對應位上的值相同,則該位的結(jié)果為0。,“按位異或”的應用,使特定位翻轉(zhuǎn),即使指定的位求反。,【例11.6】設(shè),x=46,,將其高4位保留原樣,低4位各位求反。,main(),char x=46;,printf,(“
6、%dn”,x);,x=x15;,printf,(“%dn”,x);,11.1 位運算符,輸出結(jié)果為:,46,33,對變量置零。每一個數(shù)與它自身進行“異或”運算,結(jié)果各位均為零。即:,xx=0。,【,例11.7】不用臨時變量,交換兩個變量的值。,main(),char x=12,y=10;,printf,(“%d,%dn”,x,y);,x=xy;y=yx;x=xy;,printf,(“%d,%dn”,x,y);,輸出結(jié)果為:,12,10,10,12,11.1 位運算符,“按位取反”運算(),“,按位取反”運算符“”是唯一的一個單目位運算符,用來將一個二進制數(shù)按位取反,即將1變0,將0變1。,【例
7、11.8】給出一個數(shù)的原碼,求出該數(shù)的補碼。,main(),unsigned,int,a;/*,聲明一個無符號的整數(shù),a*/,unsigned,int getbits,(unsigned);/*,函數(shù)聲明*/,printf,(,nInput,an octal number:);,scanf,(%o,/*,以八進制形式輸入一個無符號的整數(shù)*/,printf,(result:%o,getbits,(a);/*,以八進制形式輸出*/,11.1 位運算符,unsigned,int getbits,(unsigned value)/*,求一個二進制數(shù)的補碼*/,unsigned,int,z;,z=val
8、ue,if(z=10000000),z=value+1;/*,對負數(shù)求其補碼*/,else,z=value;/*,正數(shù)不變*/,return(z);,運行情況如下:,Input an octal number:2345,result:2345,再次運行:,Input an octal number:1252525,result:5253,11.1 位運算符,“左移”運算(),左移運算符“”是雙目運算符,左移運算的一般形式為:,運算對象左移位數(shù),作用:將一個數(shù)的各二進制位依次左移若干位(由左移位數(shù)給出),左移時,右端(低位)補0,左端(高位)移出的部分舍去。,【例11.9】輸入兩個1位十進制數(shù)字
9、符,a,和,b,,由,a、b,組合生成整數(shù),c(c,用字符類型表示),并顯示出來。生成規(guī)則是:,a,的低4位作為,c,的高4位,,b,的低4位作為,c,的低4位。,屏蔽掉,a,b,的高4位;,a,左移4位,使,a,的低4位成為高4位;,將,a,和,b,拼在一起,形成,c。,11.1 位運算符,main(),char a,b,c;,while(1)/*,輸入,a,b*/,printf,(Please input a and b:n);,scanf,(%c%c,if(a=0),a=a),右移運算符“”是雙目運算符,右移運算的一般形式為:,運算對象右移位數(shù),作用:將一個數(shù)的各二進制位依次右移若干位(
10、由右移位數(shù)給出),右移時,右端(低位)移出的部分舍去,左端(高位)移入的二進制數(shù)分兩種情況:對于無符號數(shù)和正整數(shù),高位補0;對于負整數(shù),高位補1。,例如:,int,a=5,b=-3,x,y;,x=a2;,y=b2;,11.1 位運算符,位復合賦值運算符,注意,位運算的類型可以是整型(,int,、unsigned,或,long,int,),或字符型(,char),數(shù)據(jù)。,當兩個運算對象的類型不同時系統(tǒng)會自動進行如下處理:,兩個運算對象按位右對齊;,較短的運算對象高位符號擴展;即如果是正數(shù),高位補0,如果是負數(shù),高位補1。,11.2 位段,位段結(jié)構(gòu)類型,位段結(jié)構(gòu)是一種構(gòu)造類型,類型定義的方法為:,
11、struct,類型名,基類型 位段名1:位段1占用位數(shù);,基類型 位段名2:位段2占用位數(shù);,;,基類型 位段名,n:,位段,n,占用位數(shù);,;,11.2 位段,例如,,struct,status,unsigned a:2;,unsigned b:2;,unsigned c:3;,unsigned d:3;,unsigned e:1;,unsigned f:2;,unsigned g:3;,;,11.2 位段,位段結(jié)構(gòu)類型變量的定義與引用,位段結(jié)構(gòu)類型的變量,位段結(jié)構(gòu)類型的變量的定義方法和其它變量定義方法一樣。,例如利用上面定義的類型,status,可以定義變量,flag,,struct,st
12、atus flag;,位段數(shù)據(jù)的引用,位段數(shù)據(jù)的引用方法和結(jié)構(gòu)體成員的引用方式相同。,例如,,flag.a=2;flag.b=1;,如果所賦值超過了位段所允許的最大范圍,系統(tǒng)會自動取數(shù)的低位。,關(guān)于位段的說明,位段的基類型必須,為,unsiged int,類型。,11.2 位段,可以將類型說明和變量說明一起完成。,struct,packed1,unsigned f1:4;,unsigned f2:2;,unsigned f3:2;,data1;,在位段結(jié)構(gòu)中可以定義無名位段。無名位段起位段之間的分隔作用。,struct,packed2,unsigned f1:4;,unsigned f2:2;
13、,unsigned :2;/*,無名位段,起分隔作用*/,unsigned f3:2;,data2;,11.2 位段,無名位段的長度可以為0,這時,下一個位段從下一個單元存放。,struct,packed3,unsigned f1:4;,unsigned f2:4;,unsigned :0;/*,無名位段長度為0*/,unsigned f3:2;,data3;,11.2 位段,一個位段必須存儲在同一存儲單元,不能橫跨兩個存儲單元。如果一個單元空間不夠,則系統(tǒng)從下一個單元起存放該位段。,struct,packed4,unsigned f1:8;,unsigned f2:4;,unsigned f
14、3:6;/*,該位段從下一個單元起存放*/,unsigned f4:2;,data4;,11.2 位,段,在位段結(jié)構(gòu)中,不一定必須是位段成員,也可以包含非位段成員。,struct,packed5,unsigned f1:4;,unsigned f2:4;,unsigned f3:4;,int,n;/*,非位段成員*/,data5;,位段可以在數(shù)值表達式中引用,并被系統(tǒng)自動轉(zhuǎn)換成整型數(shù)。位段可以在表達式中引用,所以位段也可以以整型格式輸出。例如:,printf,(“%d,%d”,data2.f1,data1.f2);,11.3應用舉例,【,例11.10】取一個整數(shù),a(,用16位存儲)從右端開始
15、的47位。,解:例如,0000,0000,1101,1001(八進制331,十進制217,47位1101的八進制值是15,十進制13)。方法:,先使,a,右移4位,使要取出的幾位移到最右端。,a4,設(shè)置一個低4位全為1,其余為0 的數(shù)(0 4;/*,將,a,右移4位后賦值給變量,b*/,c=(0 4);/*,使低4位全為1,其余為0 */,d=b,printf,(“%on%on”,a,d);,11.3應用舉例,【,例11.11】從鍵盤上輸入一個十進制整數(shù),統(tǒng)計該整數(shù)所對應的二進制數(shù)中1的個數(shù)。,分析:統(tǒng)計一個整數(shù),m,中1的個數(shù)有兩種方法。,方法1:,循環(huán)執(zhí)行、,測試,m,的第0位是否為1,是
16、則1的個數(shù)加1;,m,右移1位;,程序如下:,main(),int,i,count,m;,printf,(Please input m:);,scanf,(%d,count=0;,11.3應用舉例,for(i=0;i1;,printf,(Numbers of 1 in m=%d,count);,方法2:,k=1;,循環(huán)執(zhí)行、,測試,m,的第,k,位是否為1,是則1的個數(shù)加1;,k,左移1位。,11.3應用舉例,程序如下:,main(),int,i,count,m,k;,printf,(Please input m:);,scanf,(%d,count=0;,k=1;,for(i=0;i=16;i+),if(m&k)!=0),count+;,k=k0111101111110101,(注意,不能直接使用運算符,因為,運算符使左面添0或添1。),方法如下:,將,a,的右端,n,位先放到中間變量,b,的高,n,位中。(左移16-,n,位),b=an;,將,c,與,b,進行按位或運算。,c=a|b,11.3應用舉例,程序如下:,main(),unsigned a,b,c;,int,n;,scan