1.按位与按位或运算符

按位与:有0则0,全1则1
按位或:有1则1,全0则0
2.按位异或 按位左移 按位右移运算符



代码如下:
cpp
#include <stdio.h>
void jh(void){ //交换两个变量的值,不使用中间变量
int a = 3, b = 10;
a = a^b;
b = a^b;
a = a^b;
printf("%d, %d\n", a, b);
}
int main(void){
int a = 123;
printf("%d, %d, %d\n", a<<38, a<<(38%32), 123<<38); //让一个数值或变量左移大于自身长度的位数,或者使用左移右移移动的位数为负值,在不同的编译器中可能结果不一致,我们应该尽量避免这种情况的发生。
return 0;
}
执行结果如下:

3.位运算符的综合应用
代码如下:
cpp
#include <stdio.h>
#include <stdlib.h>
int add(int a, int b) { //利用位运算来实现两个整数加法
int c;
while(c = a&b) {
a = (c^a) | (c^b);
b = c<<1;
}
return a|b;
}
int pv(int a, int index) { //查看int a的二进制形式的第index位是1还是0
if(index <= 0 || index > 32) {
printf("函数参数有误,程序退出\n");
exit(-1);
}
return 1&(a>>index-1);
}
int po(int a, int index) { //将int a的二进制形式的第index位打开(如果为0就改成1,如果为1就不变)
if(index <= 0 || index > 32) {
printf("函数参数有误,程序退出\n");
exit(-1);
}
return a|(1<<index-1);
}
int pc(int a, int index) { //将int a的二进制形式的第index位关闭
if(index <= 0 || index > 32) {
printf("函数参数有误,程序退出\n");
exit(-1);
}
return (~(1<<index-1)) & a;
}
unsigned pd(unsigned a, int start, int end) { //返回a的二进制形式从start位到end位的内容
if(start > 0 && start <= end && end <=32) {
return a << 32-end >> 32-(end+1-start);
}
printf("pd函数参数有误,程序退出\n");
exit(-1);
}
unsigned pf(unsigned a,unsigned b, int start, int end) {
if(start > 0 && start <= end && end <=32) {
int len = end+1-start;
for(int i = 1; i <= len; ++i) {
if(pv(b,i))
a = po(a,start++);
else
a = pc(a,start++);
}
return a;
}
printf("pd函数参数有误,程序退出\n");
exit(-1);
}
int mul(int a, int b){ //通过位运算进行整数相乘
int s = 0;
for(int i = 1; i <= 32; ++i){
if(pv(b,i))
s += a<<i-1;
}
return s;
}
int chufa(int a, int b){
if(b == 0){
printf("0不能做除数,程序退出\n");
exit(-1);
}
if(a == 0)
return 0;
int a0 = pv(a,32);
int b0 = pv(b,32);
int zheng;
if(a0^b0 == 0)
zheng = 1;
else
zheng = 0;
if(a0){
a = ~(a-1);
}
if(b0)
b = ~(b-1);
for(int i = 31; i >=1; --i){
if(pv(a,i))
break;
}
int shang = 0, bc = 1;
while(i-- != 0){
if(b>bc){
shang <<= 1;
if(i != 0)
bc = bc<<1|pv(a,i);
}
else{
shang = shang<<1|1;
if(i != 0)
bc = bc<<1|pv(a,i);
}
}
return zheng?shang:~shang+1;
}
int main(void) {
printf("%d\n", add(-23, 14));
printf("%d\n", pv(13, 2));
printf("%d\n", po(13, 2));
printf("%d\n", pc(13, 3));
printf("%u\n", pd(145, 3, 6));
printf("%u\n", pf(15, 4, 2, 3));
printf("%d\n", mul(12,4));
printf("%d\n", chufa(13,2));
return 0;
}
执行结果如下:

4.位段


