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=xy;
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 00012
~(0x012)0xd5
b、请把0xed的第3位进行清零操作
0xed=1110 1101=1110 0101
1111 0111
~
0000 1000
= 0000 00013
~(0x013)0xed
c、请把0x7d的第2-4位进行清零
0x7d=0111 1101=0110 0001
1110 0011
~
0001 1100
=
0000 01112
~(0x07)0x7d
d、请把0x7d的第2位和第3位进行清零
0x7d=0111 1101=0111 0001
1111 0011
~
0000 1100
0000 00112
~(0x032)0x7d
e、请把0xc7的第4位进行置1
0xc7=1100 0111=1101 0111
0001 0000
=0000 00014
=~(0x014)|0xc7
f、请把0x87的第3位进行置1
0x87=1000 0111=1000 1111
0000 1000
~(0x013)|0x87
g、请把0xc7的第3—5位置1
0xc7=1100 0111=1111 1111
0011 1000
0000 01113
~(0x073)|0x87
C语言中按位与(&)运算符是什么意思
是将二进制数按照位的对应相与,得到一个新的二进制数。1与0为0;1与1为1;0与0为0。
分析如下:
就是二进制的每一位相与。
比如:1010 0011 0000 1111,结果为0000 0011。也就是与上0相当于把那位数清0,与上1相当于把那位保留。
扩展资料:
1、按位与运算符””是双目运算符。 其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。
例如:95可写算式如下: 00001001 (9的二进制补码)00000101 (5的二进制补码) 00000001 (1的二进制补码)可见95=1。 按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a255 运算 ( 255 的二进制数为11111111)。
参考资料:百度百科:位运算符
C语言位运算
C语言提供的位运算:
运算符
含义
按位与
|
按位或
∧
按位异或
∽
取反
左移
右移
说明:
1。位运算符中除∽以外,均为二目(元)运算符,即要求两侧各有一个运算了量。
2、运算量只能是整形或字符型的数据,不能为实型数据。
“按位与”运算符()
规定如下:
00=0
01=0
10=0
11=1
例:35=?
先把3和5以补码表示,再进行按位与运算。
3的补码:
00000011
5的补码:
00000101
——————————————————————————–
:
00000001
35=1
“按位或”运算符(|)
规定如下:
0|0=0
01=1
10=1
11=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=a2
将a的二进制数左移2位,右补0。
若a=15,即二进制数00001111,则
a
00001111
↓
↓
a1
00011110
↓
↓
a2
00111100
最后a=60
右移运算符()
将一个数的二进位全部右移若干位,低位移出部分舍弃。
例:a=a2
将a的二进制数右移2位,左补0。
若a=15,即二进制数00001111,则
a
00001111
↓
↓
a1
00000111
↓
↓
a2
00000011
最后a=3
位运算符与赋值运算符结合可以组成扩展的赋值运算符
如:=,|=,=,=,∧=
例:a=b相当于a=ab
a=2相当于a=a2
不同长度的数据进行位运算
如果两个数据长度不同(例如long型和int型)进行位运算时(如ab,而a为long型,b为int型),系统会将二者按右端对齐。如果b为正数,则左侧16位补满0。若b为负,左端应补满1。如果b为无符号整数型,则左端添满0。
位运算举例
例:取一个整数a从右端开始的4∽7位
考虑如下:1、先是a右移4位,即a4
2、设置一个低4位全为0的数,即∽(∽04)
3、将上面两式进行与运算,即a4∽(∽04)
程序如下:
main()
{unsigned
a,b,c,d;
scanf(“%o”,a);
b=a4;
c=∽(∽04);
d=bc;
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=an
3、将c与b进行按位或运算,即c=c|b
程序如下:
main()
{unsigned
a,b,c;int
n:
scanf(“a=%o,n=%d”,a,n);
b=a(16-n);
c=an;
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;