C语言位运算
C语言课件第12章 位运算

1.
位运算规则: 位运算规则: A 0 0 1 1 B 0 1 0 1 A&B 0 0 0 1 A|B 0 1 1 1 A^B 0 1 1 0 ~a 1 1 0 0
例12.1 若 a=(15)10=(00001111)2, a=(15) b=(80)10=(01010000)10 则: a&b = 0000 0000, a|b = 0101 1111, a^b =01011111 , ~a = 1111 0000
/*设 a 为待处理的数据,转换成二进制为00001000, /*设 为待处理的数据,转换成二进制为00001000, b用来保存将a的高4位清0后的结果*/ 用来保存将a的高4位清0后的结果* main() { unsigned char a,b,c; a=8; b=a&0x0f; c=b|0xa0; /*c用于保存最终结果*/ b=a&0x0f; c=b|0xa0; /*c用于保存最终结果 用于保存最终结果* printf("%x" printf("%x",c); }
4)左移,右移运算实现将一个数的各个二进制位向左,向 4)左移,右移运算实现将一个数的各个二进制位向左,向 右移若干位. 左移:将一个数的各个二进制位左移若干位,高位左移 左移:将一个数的各个二进制位左移若干位, 后舍弃,低位补0 后舍弃,低位补0 . 若定义: 若定义: int a=8; 即a= 0000 1000 0010 0000 0000 右移:将一个数的各个二进制位右移若个位,低位右移 右移:将一个数的各个二进制位右移若个位, 后舍弃, 还是补1 后舍弃,高位补 0还是补1,要区别有符号数还是无符号 无符号数高位补0 有符号数高位补原符号位. 数:无符号数高位补0,有符号数高位补原符号位. 若定义 unsigned int a=8; 即 00001000, a=8; 00001000, 则语句 a=a>>2 ;将 a 的各二进制位右移 2 位,空出的 高位补 0.结果为: 0000 0010 , 则语句a=a<<2; 则语句a=a<<2;
C语言位运算

第8章位运算C语言是为描述系统而设计的,与其它高级语言相比,它的一个重要特点是具有汇编语言的功能,这主要表现在C语言提供了特有的位运算功能。
8.1 位运算概念C语言的位运算是指在C语言中能进行二进制位的运算。
位运算包括位逻辑运算和移位运算,位逻辑运算能够方便地设置或屏蔽内存中某个字节的一位或几位,也可以对两个数按位相加等;移位运算可以对内存中某个二进制数左移或右移几位等。
为了表示数值,可以采用不同的方法,一般有:原码、反码和补码。
计算机内部是以补码形式存放数值的。
8.2 位运算符C语言提供了六种位运算,如表8-1所示。
表8-1 位运算符及含义说明:1.位运算量a,b只能是整型或字符型的数据,不能为实型数据。
2.位运算符中除按位取反运算符~为单目运算符外,其它均为双目运算符,即要求运算符的两侧各有一个运算量。
8.2.1位逻辑运算符假设a,b为整型的数据,并且设a=123(等于二进制数00000000001111011),b=152(等于二进制数00000000010011000)1.“按位与”运算符&运算规则:参加运算的两个运算量,如果两个数相应位的值都是1,则该位的结果值为1,否则为0。
即:0 & 0 =0;0 & 1 =0;1 & 0 =0;1 & 1 =1。
【例8-1】a的补码:00000000001111011b的补码:00000000010011000& ————————结果的补码:00000000000011000即:a&b=0x18。
2.“按位或”运算符|运算规则:参加运算的两个运算量,如果两个数相应位的值都是0,则该位的结果值为0,否则为1。
即:0 | 0 =0;0 | 1 =1;1 | 0 =1;1 | 1 =1【例8-2】a的补码:00000000001111011b的补码:00000000010011000| ————————结果的补码:00000000011111011即:a|b=0xfb。
C语言中的位运算的技巧

C语⾔中的位运算的技巧⼀、位运算实例1、⽤⼀个表达式,判断⼀个数X是否是2的N次⽅(2,4,8,16.....),不可⽤循环语句。
X:2,4,8,16转化成⼆进制是10,100,1000,10000。
如果减1则变成01,011,0111,01111。
两者做按位与运算,结果如果为0,则X是2的N次⽅。
2、统计⼀个整数的⼆进制中1的个数int count_number_of_one(int number){ int counter = 0; while (number) { counter++; number &= number - 1 ; } return counter;}⼆、位运算基础很多⾼级的动态规划题⽬或者⼀些基础的运算往往需要较⾼的执⾏效率和较低的空间需求,或者需要表⽰⼀些状态集合,⽽位运算刚好能满⾜这⼀切。
很多的时候,恰当的位运算使⽤也能使程序变得更加简洁和优美。
1、位运算法则位运算是各位互不影响的,⽐如A为1010⽽B为1100,那么有A&B=1000A|B=1110A^B=0110~A=11110101 (1的个数是取决于A的类型的,这⾥认为A的类型是8位整型)另外两种位运算是位移运算a<<b,a>>b。
前者表⽰将a的所有位向左移动b位,后者则表⽰将a的所有位向右移动b位。
对于⾮负整数(往往这也是我们最关⼼的),新空出的位将会被0取代。
⽐如A为1001,⽽B为3,那么A>>B则为1。
⼤多数情况下可以简单地认为左移b位就是乘以2b,⽽右移b位则是除以(整除)2b。
当然这是存在例外的——对于负数是不能这么简单认为的:⽐如在GNU GCC/G++ 编译条件下,若A=-1,你会发现对于任何位移运算A<<B,⽆论B的取值如何,其结果均为-1。
因此请注意,在位移运算下务必确保对⾮负整数进⾏运算,以免发⽣不必要的问题。
对于位移运算最常⽤的操作就是取⼀个特定的位——⽐如1< xx>2、对于集合的表⽰⼤多数时候,我们可以⽤⼀个整数来表⽰⼀个包含不超过32(当然如果使⽤64位整型变量也可以是64个)个元素的集合——对于每⼀个位,如果元素为1,则表⽰存在当前位所对应的集合成员,如果是0,则表⽰这个集合成员是不存在的。
C语言的位运算

C语言的位运算位运算是指按二进制进行的运算。
在系统软件中,常常需要处理二进制位的问题。
C语言提供了6个位操作运算符。
这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。
C语言提供的位运算符列表:&,按位与,如果两个相应的二进制位都为1,则该位的结果值为1,否则为0|,按位或,两个相应的二进制位中只要有一个为1,该位的结果值为1^ ,按位异或,若参加运算的两个二进制位值相同则为0,否则为1~ ,取反,~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0<<,左移,用来将一个数的各二进制位全部左移N位,右补0>>,右移,将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补01、“按位与”运算符(&)按位与是指:参加运算的两个数据,按二进制位进行“与”运算。
如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。
这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false。
按位与其实与逻辑上“与”的运算规则一致。
逻辑上的“与”,要求运算数全真,结果才为真。
若,A=true,B=true,则A∩B=true 例如:3&5 3的二进制编码是11(2)。
(为了区分十进制和其他进制,本文规定,凡是非十进制的数据均在数据后面加上括号,括号中注明其进制,二进制则标记为2)内存储存数据的基本单位是字节(Byte),一个字节由8个位(bit)所组成。
位是用以描述电脑数据量的最小单位。
二进制系统中,每个0或1就是一个位。
将11(2)补足成一个字节,则是00000011(2)。
5的二进制编码是101(2),将其补足成一个字节,则是00000101(2)按位与运算:00000011(2)&00000101(2)00000001(2)由此可知3&5=1c语言代码:#include <stdio.h>main(){int a=3;int b = 5;printf("%d",a&b);}按位与的用途:(1)清零若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:原来的数中为1的位,新数中相应位为0。
c语言位运算优先级

c语言位运算优先级C语言中的位运算是指对二进制数进行运算的操作。
位运算是一种快速且高效的运算方式,可以在一次计算中同时处理多个数位。
在C语言中,位运算具有特定的优先级,即不同的位运算符具有不同的执行顺序。
本文将重点介绍C语言中位运算的优先级及其使用方法。
在C语言中,位运算的优先级由高到低依次为:~(取反)、<<(左移)、>>(右移)、&(按位与)、^(按位异或)和|(按位或)。
位运算的优先级规定了在表达式中多个位运算符同时出现时的执行顺序。
下面将分别介绍各个位运算符及其优先级。
1. ~(取反)运算符:~是一元运算符,用于对一个数的每一位取反。
它的优先级最高,可以直接作用于一个数或表达式。
例如,~3的结果是-4,因为3的二进制表示为0000 0011,取反后为1111 1100,再转换为十进制即为-4。
2. <<(左移)和 >>(右移)运算符:<<是二元运算符,用于将一个数的二进制表示向左移动指定的位数,右边空出的位用0填充。
>>也是二元运算符,用于将一个数的二进制表示向右移动指定的位数,左边空出的位用符号位填充。
左移和右移运算符的优先级次于~运算符。
例如,8 << 2的结果是32,因为8的二进制表示为0000 1000,向左移动2位后变为0010 0000,即32。
3. &(按位与)运算符:&是二元运算符,用于对两个数的每一位进行与运算。
它的优先级次于<<和>>运算符。
例如,3 & 5的结果是1,因为3的二进制表示为0000 0011,5的二进制表示为0000 0101,按位与后得到0000 0001,即1。
4. ^(按位异或)运算符:^是二元运算符,用于对两个数的每一位进行异或运算。
它的优先级次于&运算符。
例如,3 ^ 5的结果是6,因为3的二进制表示为0000 0011,5的二进制表示为0000 0101,按位异或后得到0000 0110,即6。
C语言位运算

位运算一、基本概念:1、概念:C语言提供了对二进制数中的某个位或某几位进行操作的运算符,称为位运算。
2、特点:不再将数据作为一个整体进行运算,而是对数据中的某个或某几个二进制位进行的运算。
3、用途:可直接用于编写系统程序,常用在检测和控制领域。
4、无符号数适用于只有正数和0的场合。
(可表示范围:0~2n-1)5、有符号纯整数的二进制表示有3种形式:(原码、反码、补码)(1)原码:如果用n位二进制表示一个数,用最高位表示符号,最高位为1表示负数,最高位为0表示正数,剩下的n-1位表示数值,数值部分用其绝对值表示,这种表示方法称为原码。
二进制原码的表示范围:-2n-1<x<2n-1。
例:十进制55D转换为二进制为:00110111B。
十进制-55D转换为二进制为:10110111B。
(2)反码:用n位二进制表示数据,仍然用最高位表示符号,1表示负,0表示正,剩下的n-1为表示数值(正数不做任何变换,保持不变,负数符号位不变其余各位按位取反(0变为1,1变为0)),这种表示方法称为反码。
(表示的数据范围与原码相同)例:十进制55D转换为二进制为:00110111B十进制-55D转换为二进制为:11001000B。
(3)补码:利用有模运算表示数据的一种方式。
如果用n位二进制表示数据,则系统的模是2n。
对任意一个范围在-2n-1≤x<2n-1的数X,其补码表示为:=2n+X。
[X]补例:十进制55D转换为二进制为:100000000+00110111=00110111B 十进制-55D转换为二进制为:100000000-00110111=11001000B二、位运算逻辑位运算符移位位运算符符号含义符号含义~按位取反(单目)<<左移(双目) &按位与(双目)|按位或(双目)>>右移(双目)∧按位异或(双目)1、按位与的作用:(1)全部清零:将一个需要全部清零的数与零做按位与运算。
《C语言程序设计》第十章位运算(完)

运行结果: a and b:0x81 a and b:0xbb a and b:0x3a
1 0 1 1 1 0 0 1 a:0xb9 a&b 1 0 0 0 0 0 1 1 b:0x83
1 0 0 0 0 0 0 1 结果:0x81
1 0 1 1 1 0 0 1 a:0xb9 a|b 1 0 0 0 0 0 1 1 b:0x83
unsigned char b=248 b>>2 1 1 1 1 1 0 0 0
补零
00111110
舍弃
不带符号的操作数右移位时,左端出现的空 位补零。
unsigned char b=248 b>>2 1 1 1 1 1 0 0 0
补零
00111110
舍弃
说明:
4) 每右移一位相当于操作数除2。 5) a>>2,b>>2形式的操作并不改变操作数a,b
b=a<<2 舍弃
0 0 0 1 1 0 1 1 a:0x1b
0 1 1 0 1 1 0 0 b:0x6c 补零
不带符号的操作数右移位时,左端出现的空 位补零。
带符号的操作数右移位时,左端出现的空位 按原最左端的位复制,无论什么操作数,移 出右端的位被舍弃。
例[10-4]:右移位操作。
void main(){ char a=-8; unsigned char b=248; printf("signed a right_shift 2 bit:%d\n", a>>2 ); printf("unsigned b right_shift 2 bit:%d\n", b>>2 ); }
C语言位运算符(附例题讲解)

C语言提供了六种位运算符:& 按位与| 按位或^ 按位异或~ 取反<< 左移>> 右移12.1.1按位与运算按位与运算符"&"是双目运算符。
其功能是参与运算的两数各对应的二进位相与。
只有对应的两个二进位均为1时,结果位才为1,否则为0。
参与运算的数以补码方式出现。
例如:9&5可写算式如下:00001001 (9的二进制补码)&00000101 (5的二进制补码)00000001 (1的二进制补码)可见9&5=1。
按位与运算通常用来对某些位清0或保留某些位。
例如把a 的高八位清0 ,保留低八位,可作a&255运算( 255 的二进制数为0000000011111111)。
【例12.1】main(){int a=9,b=5,c;c=a&b;printf("a=%d\nb=%d\nc=%d\n",a,b,c);}12.1.2按位或运算按位或运算符“|”是双目运算符。
其功能是参与运算的两数各对应的二进位相或。
只要对应的二个二进位有一个为1时,结果位就为1。
参与运算的两个数均以补码出现。
例如:9|5可写算式如下:00001001|0000010100001101 (十进制为13)可见9|5=13【例12.2】main(){int a=9,b=5,c;c=a|b;printf("a=%d\nb=%d\nc=%d\n",a,b,c);}12.1.3按位异或运算按位异或运算符“^”是双目运算符。
其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。
参与运算数仍以补码出现,例如9^5可写成算式如下:00001001^0000010100001100 (十进制为12)【例12.3】main(){int a=9;a=a^5;printf("a=%d\n",a);}12.1.4求反运算求反运算符~为单目运算符,具有右结合性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言位运算
0或者1值的运算对象出发,计算出具有0或者1 值的结果。
C语言提供了6种基本位运算功能:位否定、位与、位或、位异或、位左移和位右移。
其中除位否定是单目运算外,其余5种均为
双目运算,6个位运算符分为4个优先级别,参见表3-9。
表3-9 逻辑运算符
运算符含义运算对象个数结合方向优先级
~ 按位求反单目运算符自右向左1
<< 按位左移双目运算符自左向右2
>> 按位右移双目运算符自左向右2
& 按位与双目运算符自左向右3
| 按位或双目运算符自左向右4
^ 按位异或双目运算符自左向右5
说明:
①位运算的优先级是:~→<<、>>→&→|→^。
②位运算的运算对象只能是整型(int)或字符型(char)的数据。
③位运算是对运算量的每一个二进制位分别进行操作。
3.5.2 按位逻辑运算
按位逻辑运算包括:位与、位或、位异或和位否定等四种运算。
为了帮助读者理解,我们设a和b都是16位二进制整数,
它们的值分别是:
a: 1010,1001,0101,0111
b: 0110,0000,1111,1011
为了便于阅读,a和b中每4位用一个逗号分开。
以下介绍对于a和b的位与、位或、位异或和位否定等按位逻辑运算。
1.按位与运算(&)
按位与是对两个运算量相应的位进行逻辑与,"&"的运算规则与逻辑与"&&"相同。
按位与表达式:c=a&b
a: 1010,1001,0101,0111
& b: 0110,0000,1111,1011
c: 0010,0000,0101,0011
2.按位或运算(|)
按位或是对两个运算量相应的位进行逻辑或操作,其运算规则与逻辑或"||"相同。
按位或表达式:c=a|b
a: 1010,1001,0101,0111
| b: 0110,0000,1111,1011
c: 1110,1001,1111,1111
3.按位异或运算(^)
按位异或运算的规则是:两个运算量的相应位相同,则结果为0,相异则结果为1。
即:0^0=0 0^1=1 1^0=1 1^1=0
按位异或表达式:c=a^b
a: 1010,1001,0101,0111
^ b: 0110,0000,1111,1011
c: 1100,1001,1010,1100
可见,异或运算的含义是:两个相应位的值相异,则结果为1,相同则为0。
4.按位求反运算符(~)
按位求反运算运算规则是将二进制表示的运算对象按位取反,即将1变为0,将0变为1。
按位异或表达式:c=~a
~ a: 1010,1001,0101,0111
c: 0101,0110,1010,1000
5.按位逻辑运算的应用
例3-8:设int x=7,求y=~x
y=~x=~7=~(0000,0000,0000,0111)=1111,1111,1111,1000=-8
可见,对x的值(7)按位求反结果恰为-8的补码表示,其原因是计算机中有:
整数求负=整数求补=按位求反+1
所以:按位求反=整数求负-1。
请注意求反运算与单目减和逻辑非运算的区别:
y=-x; 结果为:y=-7,
y=!x; 结果为:y=0。
例3-9:用按位与运算屏蔽特定位(将指定位清为0)。
设n=051652(八进制数),计算m=n&0177,则:m=052。
n: 0,101,001,110,101,010
& 0177: 0,000,000,001,111,111
m: 0,000,000,000,101,010
经过位与运算,将n前9位屏蔽掉,即截取n的后7位。
例3-10:用按位与运算保留特定位。
要想将一个变量n的特定位保留下来,只要设一个数,使该数的某些位为1,这些位是与要保留的n的特定位相对应的
位,再将n与该数按位与。
设n=011050(为八进制数。
对应的二进制为:0,001,001,000,101,000),要将n的右起第2、4、6、8、10位保留下
来,只要n=n&01252,则有:
n: 0,001,001,000,101,000
& 01252: 0,000,001,010,101,010
n: 0,000,001,000,101,000 (n=01050)
注意,按位与的"&"功能与取地址运算的"&"不同,尽管两者采用了相同的符号。
例3-11:用按位或运算将指定的位置为1。
设:x=061,y=016,则z=a|b为:
x: 0000,0000,0011,0001
| y: 0000,0000,0000,1110
z: 0000,0000,0011,1111
即将x或y中为1的位的相应位置成1,其结果是z中的后6位为1。
例3-12:用按位异或运算将某个量的特定位翻转。
要将变量n的特定位翻转,即原来为1的变0,为0的变1,只要设一个数,使该数的某些位为1,这些位是与n中要翻转
的相对应的位,然后将n与该数进行按位异或运算。
设:a=015,要将后四位翻转,只要a=a^017,则:
a: 0000,0000,0011,1101
^ 017: 0000,0000,0011,1111
a: 0000,0000,0000,0010
3.5.3 移位运算
C语言提供了两个移位运算:左移和右移,它们是把整数作为二进制位序列,求出把这个序列左移若干位或者右移若干
位所得到的序列。
左移和右移都是双目运算,运算符左边的运算对象是被左移或右移的数据,而运算符右边的运算对象是指明移
动的位数。
数据左移或右移后空出来的位置补0。
左移、右移运算表达式的一般形式为:
x << n 或x >> n
其中x为移位运算对象,是要被移位的量;n是要移动的位数。
左移运算的规则是将x的二进制位全部向左移动n位,将左边移出的高位舍弃,右边空出的位补0。
右移是将x的各二进制位全
部向右移动n位,将右边移出的低位舍弃,左边高位空出要根据原来量符号位的情况进行补充,对无符号数则补0;对有符号
数,若为正数则补0,若为负数则补1。
例如,设a=7,则:
b=a<<2 即:b=0000,0111<<2=0001,1100=28
c=a>>2 即:c=0000,0111>>2=0000,0001=1
左移的一个特殊用途是将整数值乘以2的幂,例如:左移运算表达式1<<4的计算结果是16,右移可以用于将整数值除乘2的
幂。
3.5.4 位运算赋值运算符
位运算符与赋值运算符可以组成以下5种位运算赋值运算符:
&=、|=、>>=、<<=、^=
由这些位运算赋值运算符可以构成位运算赋值表达式。
例如:
x&=y 相当于:x=x&y
x<<=2 相当于:x=x<<2
x>>=3 相当于:x=x>>3
x^=5 相当于:x=x^5__。