C语言学习 - 位操作运算符
2019-03-01 本文已影响0人
Hyso
位运算是两个变量的二进制进行运算。
位或运算符
- 位或运算符:|
- 位或运算:
0|1 = 1
0|0 = 0
1|1 = 1 - 使用场合:对二进制数的若干位置1,其余位不变。
- 具体方法:要置1的位位或1,其余不变的位位或0。
- 位或运算实例:
#include <stdio.h>
int main(void)
{
int a = 8;
int b = 7;
printf("%d", a|b);
return 0;
}
以上程序输出:
15
解析:
8的二进制表示方式为1000,7的二进制表示方式为01111,8|7 = 15即:
1000
| 0111
= 1111
位与运算符
- 位与运算符:&
- 位与运算:
0&1 = 0
0&0 = 0
1&1 = 1 - 使用场合:对二进制数的若干位置1,其余位不变。
- 具体方法:要置0的位位与0,其余不变的位位与1。
- 位与运算实例:
#include <stdio.h>
int main(void)
{
int a = 8;
int b = 7;
printf("%d", a&b);
return 0;
}
以上程序输出:
0
解析:
8的二进制表示方式为1000,7的二进制表示方式为01111,8&7 = 0即:
1000
& 0111
= 0000
位异或运算符
- 位异或运算符:^
- 位异或运算:
0^1 = 1
0^0 = 0
1^1 = 1 - 使用场合:对二进制数的若干位置反(1变0,0变1),其余位不变。
- 具体方法:要置反的位位异或1,其余不变的位位异或0。
- 位异或运算实例:
#include <stdio.h>
int main(void)
{
int a = 8;
int b = 7;
printf("%d", a^b);
return 0;
}
以上程序输出:
15
解析:
8的二进制表示方式为1000,7的二进制表示方式为01111,8^7 = 15即:
1000
^ 0111
= 1111
位非运算符
- 位非运算符:~
- 位非运算:
~1 = 0
~0 = 1 - 使用场合:对二进制数按位取反。
- 位非运算实例:
#include <stdio.h>
int main(void)
{
int a = 8;
printf("%d", ~a);
return 0;
}
以上程序输出:
-9
解析:
在内存中,数值都是以二进制补码形式保存的。正数的补码和原码一样,负数求补码的规则为符号位不变,将剩余位取反,得到反码,在反码的基础上最后一位加1。
8的二进制表示方式:0000,0000,0000,0000,0000,0000,0000,1000
~8的二进制表示方式:1111,1111,1111,1111,1111,1111,1111,0111
符号位(最左边位)为1,表示负数,按照负数求补码的规则,符号位不变,将剩余位取反,得到反码:
1000,0000,0000,0000,0000,0000,0000,1000
在反码的基础上最后一位加1:
1000,0000,0000,0000,0000,0000,0000,1001
- 位非运算小技巧:
~(n) = -(n+1)
移位运算
- 移位运算针对整型
- 移位运算可分为:左移和右移
- 左移分为逻辑左移和算术左移
左移运算:a<<n 即把a乘以2的n次幂,如:10<<3 即 10*2^3=80
【逻辑左移】:
正数:低位补0高位丢失
负数:低位补0高位丢失
【算术左移】:
正数: 低位补0高位丢失
负数:低位补0高位丢失 - 右移分为逻辑右移和算术右移
在右移中对于负数采用逻辑右移还是算术右移取决于编译器(gcc采用算术右移)。
右移运算:a>>n 即把a除以2的n次幂,如:80>>3 即 80/2^3=10
【逻辑右移】:
正数:高位补0低位丢失
负数:高位补0低位丢失
【算术右移】:
正数:高位补0低位丢失
负数:高位补1低位丢失 - 位移运算实例:
#include <stdio.h>
int main(void)
{
int a = 10;
int b = 40;
printf("a<<5:%d\n", a<<5);
printf("b>>3:%d\n", b>>3);
return 0;
}
以上程序输出:
a<<5:320
b>>3:5