含义
&
按位与
|
按位或
∧
按位异或
∽
取反
<<
左移
>>
右移
说明:
1。位运算符中除∽以外,均为二目(元)运算符,即要求两侧各有一个运算了量。
2、运算量只能是整形或字符型的数据,不能为实型数据。
“按位与”运算符(&)
规定如下:
0&0=0
0&1=0
1&0=0
1&1=1
例:3&5=?
先把3和5以补码表示,再进行按位与运算。
3的补码:
00000011
5的补码:
00000101
--------------------------------------------------------------------------------
&:
00000001
3&5=1
“按位或”运算符(|)
规定如下:
0|0=0
0&1=1
1&0=1
1&1=1
例:060|017=?
将八进制数60与八进制数17进行按位或运算。
060
00110000
017
00001111
--------------------------------------------------------------------------------
|:
00111111
060|017=077
“异或”运算符(∧),也称XOR运算符
规定如下:
0∧0=0
0∧1=1
1∧0=1
1∧1=0
例:57∧42=?
将十进制数57与十进制数42进行按位异或运算。
57
00111001
42
00101010
--------------------------------------------------------------------------------
∧:
00010011
57∧42=19
“取反”运算符(∽)
规定如下:
∽0=1
∽1=0
例:∽025=?
对八进制数25(即二进制0000000000010101)按位求反。
0000000000010101
↓
1111111111101010
∽025=177752
左移运算符(<<)
将一个数的二进位全部左移若干位,若高位左移后溢出,则舍弃,不起作用。
例:a=a<<2
将a的二进制数左移2位,右补0。
若a=15,即二进制数00001111,则
a
00001111
↓
↓
a<<1
00011110
↓
↓
a<<2
00111100
最后a=60
右移运算符(>>)
将一个数的二进位全部右移若干位,低位移出部分舍弃。
例:a=a>>2
将a的二进制数右移2位,左补0。
若a=15,即二进制数00001111,则
a
00001111
↓
↓
a>>1
00000111
↓
↓
a>>2
00000011
最后a=3
位运算符与赋值运算符结合可以组成扩展的赋值运算符
如:&=,|=,>>=,<<=,∧=
例:a&=b相当于a=a&b
a<<=2相当于a=a<<2
不同长度的数据进行位运算
如果两个数据长度不同(例如long型和int型)进行位运算时(如a&b,而a为long型,b为int型),系统会将二者按右端对齐。如果b为正数,则左侧16位补满0。若b为负,左端应补满1。如果b为无符号整数型,则左端添满0。
位运算举例
例:取一个整数a从右端开始的4∽7位
考虑如下:1、先是a右移4位,即a>>4
2、设置一个低4位全为0的数,即∽(∽0<<4)
3、将上面两式进行与运算,即a>>4&∽(∽0<<4)
程序如下:
main()
{unsigned
a,b,c,d
scanf("%o",&a)
b=a>>4
c=∽(∽0<<4)
d=b&c
printf("%o\n%o\n",a,b)
}
结果:331↙
331(a的值,八进制)
15
(d的值,八进制)
例:循环移位。要求将a进行右循环移位。即a右循环移n位,将a中原来左面(16-n)位右移n位。现假设两个字节存放一个整数。如右图。
考虑如下:1、先将a右端n位放到b中的高n位中,即:b=a<<(16-n)
2、将a右移n位,其左面高位n位补0,即c=a>>n
3、将c与b进行按位或运算,即c=c|b
程序如下:
main()
{unsigned
a,b,cint
n:
scanf("a=%o,n=%d",&a,&n)
b=a<<(16-n)
c=a>>n
c=c|b
printf("%o\n%o",a,c)
}
结果:a=157653,n=3↙
331(a的值,八进制)
15
(d的值,八进制)
位段
所谓位段是以位为单位定义长度的结构体类型中的成员。
例:struct
packed-data
{unsigned
a:2
unsigned
b:6
unsigned
c:4
unsigned
d:4
int
i
}data
运算:C语言的运算非常灵活,功能十分丰富,运算种类远多于其它程序设计语言。
在表达式方面较其它程序语言更为简洁,如自加、自减、逗号运算和三目运算使表达式更为简单,但初学者往往会觉的这种表达式难读,关键原因就是对运算符和运算顺序理解不透不全。
当多种不同运算组成一个运算表达式,即一个运算式中出现多种运算符时,运算的优先顺序和结合规则就会显得十分重要。
运算符号:比较特别的是,比特右移(>>)运算符可以是算术(左端补最高有效位)或是逻辑(左端补0)位移。
例如,将11100011右移3比特,算术右移后成为11111100,逻辑右移则为00011100。因算术比特右移较适于处理带负号整数,所以几乎所有的编译器都是算术比特右移。
运算符的优先级从高到低大致是:单目运算符、算术运算符、关系运算符、逻辑运算符、条件运算符、赋值运算符(=)和逗号运算符。
c语言位运算符的用法1c语言位运算符的用法如下:
一、位运算符C语言提供了六种位运算符:
&按位与
| 按位或
^ 按位异或
~ 取反
<<左移
>>右移
1. 按位与运算
按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。
例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。
按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为0000000011111111)。
main(){
int a=9,b=5,c
c=a&b
printf("a=%d/nb=%d/nc=%d/n",a,b,c)
}
2. 按位或运算
按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。
例如:9|5可写算式如下: 00001001|00000101
00001101 (十进制为13)可见9|5=13
main(){
int a=9,b=5,c
c=a|b
printf("a=%d/nb=%d/nc=%d/n",a,b,c)
}
3. 按位异或运算
按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如9^5可写成算式如下: 00001001^00000101 00001100 (十进制为12)。
main(){
int a=9
a=a^15
printf("a=%d/n",a)
}
4. 求反运算
求反运算符~为单目运算符,具有右结合性。 其功能是对参与运算的数的各二进位按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110。
5. 左移运算
左移运算符“<<”是双目运算符。其功能把“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。例如: a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。
6. 右移运算
右移运算符“>>”是双目运算符。其功能是把“>>”左边的运算数的`各二进位全部右移若干位,“>>”右边的数指定移动的位数。
例如:设 a=15,a>>2 表示把000001111右移为00000011(十进制3)。 应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时, 最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。Turbo C和很多系统规定为补1。
main(){
unsigned a,b
printf("input a number: ")
scanf("%d",&a)
b=a>>5
b=b&15
printf("a=%d/tb=%d/n",a,b)
}
请再看一例!
main(){
char a='a',b='b'
int p,c,d
p=a
p=(p<<8)|b
d=p&0xff
c=(p&0xff00)>>8
printf("a=%d/nb=%d/nc=%d/nd=%d/n",a,b,c,d)
}
c语言位运算符的用法2C语言位运算。所谓位运算,就是对一个比特(Bit)位进行操作。比特(Bit)是一个电子元器件,8个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了。
C语言提供了六种位运算符:
按位与运算(&)
一个比特(Bit)位只有 0 和 1 两个取值,只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0。例如1&1为 1,0&0为 0,1&0也为 0,这和逻辑运算符&&非常类似。
C语言中不能直接使用二进制,&两边的操作数可以是十进制、八进制、十六进制,它们在内存中最终都是以二进制形式存储,&就是对这些内存中的二进制位进行运算。其他的位运算符也是相同的道理。
例如,9 &5可以转换成如下的运算:
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001 (9 在内存中的存储)
&0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001 (1 在内存中的存储)
也就是说,按位与运算会对参与运算的两个数的所有二进制位进行&运算,9 &5的结果为 1。
又如,-9 &5可以转换成如下的运算:
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
&0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-9 &5的结果是 5。
关于正数和负数在内存中的存储形式,我们已在教程《整数在内存中是如何存储的》中进行了讲解。
再强调一遍,&是根据内存中的二进制位进行运算的,而不是数据的二进制形式其他位运算符也一样。以-9&5为例,-9 的在内存中的存储和 -9 的二进制形式截然不同:
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001 (-9 的二进制形式,前面多余的 0 可以抹掉)
按位与运算通常用来对某些位清 0,或者保留某些位。例如要把 n 的高 16 位清 0 ,保留低 16 位,可以进行n &0XFFFF运算(0XFFFF 在内存中的存储形式为 0000 0000 -- 0000 0000 -- 1111 1111 -- 1111 1111)。
【实例】对上面的分析进行检验。
00001. #include
00002.
00003. int main(){
00004. int n = 0X8FA6002D
00005. printf("%d, %d, %X ", 9 &5, -9 &5, n &0XFFFF)
00006. return 0
00007. }
运行结果:
1, 5, 2D
按位或运算(|)
参与|运算的两个二进制位有一个为 1 时,结果就为 1,两个都为 0 时结果才为 0。例如1|1为1,0|0为0,1|0为1,这和逻辑运算中的||非常类似。
例如,9 | 5可以转换成如下的运算:
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001 (9 在内存中的存储)
| 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1101 (13 在内存中的存储)
9 | 5的结果为 13。
又如,-9 | 5可以转换成如下的运算:
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
| 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-9 | 5的结果是 -9。
按位或运算可以用来将某些位置 1,或者保留某些位。例如要把 n 的高 16 位置 1,保留低 16 位,可以进行n | 0XFFFF0000运算(0XFFFF0000 在内存中的存储形式为 1111 1111 -- 1111 1111 -- 0000 0000 -- 0000 0000)。
【实例】对上面的分析进行校验。
00001. #include
00002.
00003. int main(){
00004. int n = 0X2D
00005. printf("%d, %d, %X ", 9 | 5, -9 | 5, n | 0XFFFF0000)
00006. return 0
00007. }
运行结果:
13, -9, FFFF002D
按位异或运算(^)
参与^运算两个二进制位不同时,结果为 1,相同时结果为 0。例如0^1为1,0^0为0,1^1为0。
例如,9 ^ 5可以转换成如下的运算:
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001 (9 在内存中的存储)
^ 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1100 (12 在内存中的存储)
9 ^ 5的结果为 12。
又如,-9 ^ 5可以转换成如下的运算:
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
^ 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0010 (-14 在内存中的存储)
-9 ^ 5的结果是 -14。
按位异或运算可以用来将某些二进制位反转。例如要把 n 的高 16 位反转,保留低 16 位,可以进行n ^ 0XFFFF0000运算(0XFFFF0000 在内存中的存储形式为 1111 1111 -- 1111 1111 -- 0000 0000 -- 0000 0000)。
【实例】对上面的分析进行校验。
00001. #include
00002.
00003. int main(){
00004. unsigned n = 0X0A07002D
00005. printf("%d, %d, %X ", 9 ^ 5, -9 ^ 5, n ^ 0XFFFF0000)
00006. return 0
00007. }
运行结果:
12, -14, F5F8002D
取反运算(~)
取反运算符~为单目运算符,右结合性,作用是对参与运算的二进制位取反。例如~1为0,~0为1,这和逻辑运算中的!非常类似。。
例如,~9可以转换为如下的运算:
~ 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001 (9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0110 (-10 在内存中的存储)
所以~9的结果为 -10。
例如,~-9可以转换为如下的运算:
~ 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1000 (9 在内存中的存储)
所以~-9的结果为 8。
【实例】对上面的分析进行校验。
00001. #include
00002.
00003. int main(){
00004. printf("%d, %d ", ~9, ~-9 )
00005. return 0
00006. }
运行结果:
-10, 8
左移运算(<<)
左移运算符<<用来把操作数的各个二进制位全部左移若干位,高位丢弃,低位补0。
例如,9<<3可以转换为如下的运算:
<<0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001 (9 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0100 1000 (72 在内存中的存储)
所以9<<3的结果为 72。
又如,(-9)<<3可以转换为如下的运算:
<<1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1011 1000 (-72 在内存中的存储)
所以(-9)<<3的结果为 -72
如果数据较小,被丢弃的高位不包含 1,那么左移 n 位相当于乘以 2 的 n 次方。
【实例】对上面的结果进行校验。
00001. #include
00002.
00003. int main(){
00004. printf("%d, %d ", 9<<3, (-9)<<3 )
00005. return 0
00006. }
运行结果:
72, -72
右移运算(>>)
右移运算符>>用来把操作数的各个二进制位全部右移若干位,低位丢弃,高位补 0 或 1。如果数据的最高位是 0,那么就补 0如果最高位是 1,那么就补 1。
例如,9>>3可以转换为如下的运算:
>>0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001 (9 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001 (1 在内存中的存储)
所以9>>3的结果为 1。
又如,(-9)>>3可以转换为如下的运算:
>>1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 1110 (-2 在内存中的存储)
所以(-9)>>3的结果为 -2
如果被丢弃的低位不包含 1,那么右移 n 位相当于除以 2 的 n 次方(但被移除的位中经常会包含 1)。
【实例】对上面的结果进行校验。
00001. #include
00002.
00003. int main(){
00004. printf("%d, %d ", 9>>3, (-9)>>3 )
00005. return 0
00006. }
运行结果:
1, -2
c语言位运算符的用法3一、位运算符
在计算机中,数据都是以二进制数形式存放的,位运算就是指对存储单元中二进制位的运算。C语言提供6种位运算符。
二、位运算
位运算符 &|~<<>>∧ 按优先级从高到低排列的顺序是:
位运算符中求反运算“~“优先级最高,而左移和右移相同,居于第二,接下来的顺序是按位与 “&“、按位异或 “∧“和按位或 “|“。顺序为~ <<>>&∧ | 。
例1:左移运算符“<<”是双目运算符。其功能把“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。
例如:
a<<4
指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。
例2:右移运算符“>>”是双目运算符。其功能是把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。
例如:
设 a=15,
a>>2
表示把000001111右移为00000011(十进制3)。
应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。
例3:设二进制数a是00101101 ,若通过异或运算a∧b 使a的高4位取反,低4位不变,则二进制数b是。
解析:异或运算常用来使特定位翻转,只要使需翻转的位与1进行异或操作就可以了,因为原数中值为1的位与1进行异或运算得0 ,原数中值为0的位与1进行异或运算结果得1。而与0进行异或的位将保持原值。异或运算还可用来交换两个值,不用临时变量。
如 int a=3 , b=4,想将a与b的值互换,可用如下语句实现:
a=a∧b
b=b∧a
a=a∧b
所以本题的答案为: 11110000 。