是时候总结一波逻辑运算符和位运算符了。。。。。。
其实是更想总结一下位运算符的使用小技巧来体现其实用之处
用实例验证,正确
test.c#include<iostream>using namespace std;int main(){int a = 2&3;int b = 2|3;int c = ~2;int d = 1<<4;int e = 16>>4; cout<<"2&3 = "<< a <<endl;cout<<"2|3 = "<< b <<endl;cout<<"~2 = "<< c <<endl;cout<<"1<<4 = "<< d <<endl;cout<<"16>>4= "<< e <<endl;cout<<"1^1="<<(1^1)<<endl; cout<<"0^1="<<(0^1)<<endl; return 0;}
OK,概念总结完毕(更全面的可以看此链接:C语言所有的运算符)
开始总结位运算符的实用技巧
可以用于不利用中间变量来实现两个数的交换
注意两点:
(1)要交换的两个数据必须是整型,不适用于浮点型数据
(2)要交换的两个数据必须是不同的内存地址,否则会出现错误 code:void change(int &a, int &b){if(a == b)return ;//地址一样,直接退出 a = a^b;b = a^b;a = a^b;} 按位&
(1)已知集合{0,1,...,n-1}的元素共n个,我们知道子集的个数是2^n个(不要忽略空集Φ)。现在需要将所有的子集枚举出来,我们可以递归实现,也可以利用&运算符的方法来求取。 Code#include<bits/stdc++.h>using namespace std;#define MAXN 105void GetSubset_1(int n, int a[], int current){printf("{");for(int i = 0; i < current; ++i)printf("%d ",a[i]);printf("}");puts("");int pos = current ? a[current-1]+1 : 0;for (int i = pos; i < n; ++i){a[current] = i;GetSubset_1(n,a,current+1);}}void GetSubset_2(int n){for(int i = 0; i < (1<<n); ++i)//i代表第几个子集{printf("{ ");for(int j = 0; j < n; ++j){if(i & (1<<j))//判断事件j是否发生{printf("%d ",j);}}printf("}n");}}int main(){int n = 3;int a[MAXN] = {};//GetSubset_1(n,a,0);GetSubset_2(n);return 0;}
(2)利用位与 & 运算,判断一个整数是否是2的整数次幂。由于二进制的权重是2,则一个数如果是2的整数次幂,则二进制表示的时候必然是最高位为1,其余都是0
keys:当一个数x是2的这个数次幂的时候,x&(x-1) = 0因为减去1以后恰好降一位,后面的都会置为1,而前面全是0,按位&结果就是0例子:x = 8 = (1000)2x-1 = 7 = (0111)2则1000 & 0111 = 0Code:
bool fun(int num){return ( (num>0) && ((num & (num-1)) == 0) );}(3)利用&运算符求取给定数的二进制含有1的个数,利用了(2)的思路
/**思想:将给定数的二进制从右到左消除1,直至为0,中间统计1的个数即可*/int Count_Of_Num_One(int num){int count = 0;while(num){num = num&(num-1);count++;}return count;}