c语言中位运算
1. c语言位运算是什么
运算:C语言的运算非常灵活,功能十分丰富,运算种类远多于其它程序设计语言。
在表达式方面较其它程序语言更为简洁,如自加、自减、逗号运算和三目运算使表达式更为简单,但初学者往往会觉的这种表达式难读,关键原因就是对运算符和运算顺序理解不透不全。
当多种不同运算组成一个运算表达式,即一个运算式中出现多种运算符时,运算的优先顺序和结合规则就会显得十分重要。
运算符号:
比较特别的是,比特右移(>>)运算符可以是算术(左端补最高有效位)或是逻辑(左端补0)位移。
例如,将11100011右移3比特,算术右移后成为11111100,逻辑右移则为00011100。因算术比特右移较适于处理带负号整数,所以几乎所有的编译器都是算术比特右移。
运算符的优先级从高到低大致是:单目运算符、算术运算符、关系运算符、逻辑运算符、条件运算符、赋值运算符(=)和逗号运算符。
2. c语言之中的位运算符是怎么运算的呢
C语言提供了表12—1所列出的6种位运算符以及表12-2所列出的5种扩展运算符。
表12-1
运
算
符
含
义
优
先
级
~
按位求反
高
<<
左移
低
>>
右移
&
按位与
^
按位异或
|
按位或
表12-2
扩
展
运
算
符
表
达
式
等
价
的
表
达
式
<<=
a<<=2
a=a<<2
>>=
b>>=1
b=b>>1
&=
a&=b
a=a&b
^=
a^=b
a=a^b
|=
a|=b
a=a|b
【说明】
位运算符中,只有“反求”(~)是单目运算符,即要求运算符两侧各有一个运算量,其余均为双目运算符。
运算的运算对象只能是整形或字符型数据,不能是其他类型的数据,在VC
6.0中整形数据占4个字节,字符型数据占1个字节。
参与运算时,操作数都必须首先转换成二进制形式,然后再执行相应的按位运算。
各双目运算符与赋值运算符结合可以组成扩展的赋值运算符,见表12-2.
12.2
位运算符详解
12.2.1
按位与运算
按位与运算“&”的运算格式:
操作数1&操作数2
【说明】
其中“操作数1”和操作数“2”必须是整型或字符型数据。
按位与运算规则是:当参加运算的2个二进制数的对应位都为1,则该位的结果为1,否则为0,即0&0=0,0&1=0,1&0=0,1&1=1。
【例如】
4&5的运算如下:
00000100
(4)
(&)
00000101
(5)
00000100
(4)
因此,4&5的值为4。
可以利用按位与运算来实现一些特定的功能,下面介绍几种常见的功能。
清零
如果想将一个数的全部二进制置为零,只要找一个二进制数,其中个个位要符合以下条件:原来的数中为1的位,新数中相应的位为0。然后使二者进行按位与运算即可达到清零的目的。
【例如】
原有数为171,其二进制形式为10101011,另找一个数,设它为00010100,它符合以上条件,即在原数为1的位置上,它的位值均为0。将两个数进行&运算:
10101011
(&)
00010100
00000000
当然也可以不用00010100这个数而用其他数(如01000100)也可以,只要符合上述条件即可。任何一个数与“0”按位于之后的结果为0。
娶一个数中某些指定位
【例如】
有一个两字节的短整型数x,想要取其中的低字节,只要将x与八进制数(377)8按位于即可。如图12-1所示,经过运算“z=x&y”后z只保留x的低字节,高字节为0.
x
00
10
11
00
10
10
11
00
y
00
00
00
00
11
11
11
11
z
00
00
00
00
10
10
11
00
图12-1
取x的低八位数
x
00
10
11
00
10
10
11
00
y
11
11
11
11
00
00
00
00
Z
00
10
11
00
00
00
00
00
图12-2
取x的高8位
如果想取两个字节中的高字节,如图12-2所示只需进行运算z
=
x
&(177400)8。
保留一个数的某些位
要想将哪一位保留下来,就与一个数进行&运算,此数在该位取1。
【例如】
有一数01110100,想把其中左面第1、3、5位保留下来,可以这样运算:
01110100
(十进制数116)
(&)
10101010
(十进制数170)
00100000
(十进制数32)
3. C语言 位运算
###位运算的逻辑:
1:(位与)运算符(&):双目操作符,当两个位进行相与时,只有两者都为“1”时结果才为“1”(即:全真为真,一假为假),运算规则如下:
左运算量 右运算量 &运算结果
0 & 0 = 0
0 & 1 = 0
1 & 0 = 州明 0
1 & 1 = 1
运算:
例:
#include <stdio.h>
int main(int argc,char *crgv[]){
unsigned char x=0156, y=0xaf, z;
z=x&y;
printf("%d",z)
}
结果为:0x2e
运算过程:态燃0156(8进制)==0000 0110 1110(2进制);
进行 &(位与运算)
0xaf(16进制) ==0000 1010 1111(2进制);
结果:0000 0010 1110(2进制)==0x2e(十六进制);
2:位或运算符(|):
双目操作符,当两个 位 进行相或时,两者中只要有一方为“1”,结果就为“1”(即:一真为真,两假为假),运算规则如下:
左运算量 右运算量 (|) 运算结果
0 | 0 = 0
1 | 1 = 1
0 | 1 = 1
1 | 1 = 1
例:
#include <stdio.h>
int main(int argv,char *argc[]){
unsigned char x=027,y=0x75;
z=x|y;
}
运行过程:
027(8进制)=0001 0111(2进制)
进行 |(位或运算)
0x75(16进制)=0111 0101(2进制)
结果:0111 0111(2进制)=0x77(16进制)
3.异或运算(^):
当两个位进行异或时,只要两者相同,结果为“0”,否者结果为“1”,(即:同假异真)运算规则如下:
左运算量 右运算量 (^) 运算结果
0 ^ 0 = 0
1 ^ 1 帆迹虚 = 0
0 ^ 1 = 1
1 ^ 0 = 1
例:
#include
int main(int argv,char *argc[]){
unsigned(无符号) char x=25,y=0263,z;
z=x^y;
printf("%d\n",z);
}
运算过程:
25(十进制)=0001 1001(二进制)
运算 ^(异或运算)
0263(8进制)=1011 0011(二进制)
结果:1010 1010(二进制)=0252(8进制)
4:移位操作符(“<<” 或 ">>"):位移位运算的一般形式:<运算量><运算符><表达式>;
<运算量>必须为整型结果数值:
<运算符>为左移位(<<)或 右移位(>>)运算;
<表达式>也必须为整型结果数值;
移位操作就是把一个数值左移或右移若干位;假如左移n位,原来值最左边的n位数被丢掉,右边n卫补“0” ;右移操作就是和左移操作移动方向相反;
符号位的处理方法:
(1):逻辑移位,不考虑符号问题,原数值右移n位后,左边空出的n歌位置,用0填充;
(2):算术移位,原来值进行了右移操作后,需要保证符号位不变,因此,右移n位后,左边空出的n个位置,用原数值的符号位填充。原来若是负数,则符号位为“1”,填充的位也是“1”;原来若是正数,则符号位为“0”,填充的位也是“0”,这样保证移位后的数据与原数正负相同;
例:“1000 1001”将其右移两位,逻辑移位的结果为“0010 0010”,算术移位为:“1110 0010”;
将其左移两位,逻辑移位和算术移位的结果为:“0010 0100”;
(3)***补充:特定位清零(由“1”变成“0”)用 位与 操作;特定位变“1”(由“0”变成“1”)用 位或操作;
例:
a、请把0xd5的第2位进行清零操作
0xd5=1101 0101=>1101 0001
1111 1011
~0000 0100
=0000 0001<<2
~(0x01<<2)&0xd5
b、请把0xed的第3位进行清零操作
0xed=1110 1101=>1110 0101
1111 0111
~
0000 1000
= 0000 0001<<3
~(0x01<<3)&0xed
c、请把0x7d的第2-4位进行清零
0x7d=0111 1101=>0110 0001
1110 0011
~
0001 1100
=
0000 0111<<2
~(0x07)&0x7d
d、请把0x7d的第2位和第3位进行清零
0x7d=0111 1101=>0111 0001
1111 0011
~
0000 1100
0000 0011<<2
~(0x03<<2)&0x7d
e、请把0xc7的第4位进行置1
0xc7=1100 0111=>1101 0111
0001 0000
=0000 0001<<4
=~(0x01<<4)|0xc7
f、请把0x87的第3位进行置1
0x87=1000 0111=>1000 1111
0000 1000
~(0x01<<3)|0x87
g、请把0xc7的第3—5位置1
0xc7=1100 0111=>1111 1111
0011 1000
0000 0111<<3
~(0x07<<3)|0x87
4. c语言位运算
一、位运算符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);
}
5. c语言之中的位运算符是怎么运算的呢
C语言提供了表12—1所列出的6种位运算符以及表12-2所列出的5种扩展运算符。
表12-1
运 算 符 含 义 优 先 级
~ 按位求反 高
<< 左移
低
>> 右移
& 按位与
^ 按位异或
| 按位或
表12-2
扩 展 运 算 符 表 达 式 等 价 的 表 达 式
<<= a<<=2 a=a<<2
>>= b>>=1 b=b>>1
&= a&=b a=a&b
^= a^=b a=a^b
|= a|=b a=a|b
【说明】
位运算符中,只有“反求”(~)是单目运算符,即要求运算符两侧各有一个运算量,其余均为双目运算符。
运算的运算对象只能是整形或字符型数据,不能是其他类型的数据,在VC 6.0中整形数据占4个字节,字符型数据占1个字节。
参与运算时,操作数都必须首先转换成二进制形式,然后再执行相应的按位运算。
各双目运算符与赋值运算符结合可以组成扩展的赋值运算符,见表12-2.
12.2 位运算符详解
12.2.1 按位与运算
按位与运算“&”的运算格式:
操作数1&操作数2
【说明】
其中“操作数1”和操作数“2”必须是整型或字符型数据。
按位与运算规则是:当参加运算的2个二进制数的对应位都为1,则该位的结果为1,否则为0,即0&0=0,0&1=0,1&0=0,1&1=1。
【例如】
4&5的运算如下:
00000100 (4)
(&) 00000101 (5)
00000100 (4)
因此,4&5的值为4。
可以利用按位与运算来实现一些特定的功能,下面介绍几种常见的功能。
清零
如果想将一个数的全部二进制置为零,只要找一个二进制数,其中个个位要符合以下条件:原来的数中为1的位,新数中相应的位为0。然后使二者进行按位与运算即可达到清零的目的。
【例如】
原有数为171,其二进制形式为10101011,另找一个数,设它为00010100,它符合以上条件,即在原数为1的位置上,它的位值均为0。将两个数进行&运算:
10101011
(&) 00010100
00000000
当然也可以不用00010100这个数而用其他数(如01000100)也可以,只要符合上述条件即可。任何一个数与“0”按位于之后的结果为0。
娶一个数中某些指定位
【例如】
有一个两字节的短整型数x,想要取其中的低字节,只要将x与八进制数(377)8按位于即可。如图12-1所示,经过运算“z=x&y”后z只保留x的低字节,高字节为0.
x 00 10 11 00 10 10 11 00
y 00 00 00 00 11 11 11 11
z 00 00 00 00 10 10 11 00
图12-1 取x的低八位数
x 00 10 11 00 10 10 11 00
y 11 11 11 11 00 00 00 00
Z 00 10 11 00 00 00 00 00
图12-2 取x的高8位
如果想取两个字节中的高字节,如图12-2所示只需进行运算z = x &(177400)8。
保留一个数的某些位
要想将哪一位保留下来,就与一个数进行&运算,此数在该位取1。
【例如】
有一数01110100,想把其中左面第1、3、5位保留下来,可以这样运算:
01110100 (十进制数116)
(&) 10101010 (十进制数170)
00100000 (十进制数32)
6. C语言位运算
C语言提供的位运算: 运算符 含义
& 按位与
| 按位或
∧ 按位异或
∽ 取反
<< 左移
>> 右移 说明:橘激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;</p><p> scanf("%o",&a);</p><p> b=a>>4;</p><p> c=∽(∽0<<4);</p><p> d=b&c;</p><p> printf("%o\n%o\n",a,b);</p><p> } 结果: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,c;int n:</p><p> scanf("a=%o,n=%d",&a,&n);</p><p> b=a<<(16-n);</p><p> c=a>>n;</p><p> c=c|b;</p><p> printf("%o\n%o",a,c);</p><p> } 结果:a=157653,n=3↙ 331(a的值,八进制) 15 (d的值,八进制)位段
所谓位段是以位为单位定义长度的结构体类型中的成员。 例:struct packed-data {unsigned a:2;</p><p> unsigned b:6;</p><p> unsigned c:4;</p><p> unsigned d:4;</p><p> int i;</p><p> }data;
7. c语言位运算问题
位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作
运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。
C语言提供的位运算符列表:
运算符 含义 描述
& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<< 左移 用来将一个数的各二进制位全部左移N位,右补0
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
1、“按位与”运算符(&)
按位与是指:参加运算的两个数据,按二进制位进行“与”运算。如果两个相应的二进制位都为1,
则该位的结果值为1;否则为0。这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false。按位与其
实与逻辑上“与”的运算规则一致。逻辑上的“与”,要求运算数全真,结果才为真。若,
A=true,B=true,则A∩B=true 例如:3&5 3的二进制编码是11(2)。(为了区分十进制和其他进制,本文规
定,凡是非十进制的数据均在数据后面加上括号,括号中注明其进制,二进制则标记为2)内存储存数据
的基本单位是字节(Byte),一个字节由8个位(bit)所组成。位是用以描述电脑数据量的最小单位。
8. C语言中的位运算是怎样的
如果你把所有的操作数都用二进制来表达就清晰了,如下
位与 & 相同位按与来运算即可 如:
1 & 2 =0
-------------
二进制是这样的 01 & 10 = 00
位或 | 一样,按位来或即可
1|2 = 3
--------------
二进制是这样: 01|10=11
其他位运算都是按二进制位来运算的,你转换成2进制就好理解了
9. C语言中的位运算符有哪些
C 语言中有以下位运算符:
&(按位与):将两个数的二进制每一位同时与(AND)起来,并将结果赋给左操作数。盯纯
|(按位或):将两个数的二进制每一位同时或(OR)起来,并将结果赋给左操作数。
^(按位异或):将两个数的二进凯芦咐制每一位同时异或(XOR)哗梁起来,并将结果赋给左操作数。
<<(左移):将左操作数的二进制数向左移动右操作数指定的位数,并将结果赋给左操作数。
>>(右移):将左操作数的二进制数向右移动右操作数指定的位数,并将结果赋给左操作数。
~(按位取反):将左操作数的二进制数按位取反(即 1 变为 0,0 变为 1),并将结果赋给左操作数。
希望这些可以帮助到你。