1、前言
之前最开始学习语法和基础知识的时候,基本上最简单的运算符有所接触,当时对于位运算这种东西完全没有概念。今天对C++中出现的部分运算符尤其是位运算符进行一些总结。
2、+ - * / %
这些貌似不用讲吧?小学生都知道了。
3、&& ||
两大基础逻辑运算符,&&表示“和”,前后连接两个值,形如a && b,当且仅当a==1并且b==1,返回值为1,否则为0;||表示“或”,前后连接两个值,形如a || b,当a==1或者b==1时,返回值为1;否则为0。
4、<< >>
位运算符。形如a << b,表示a在二进制形式下向左移动b位。如:10 << 2 -> [1010](2) << 2 -> [101000](2) -> 40。然而只要你清楚二进制数的意义,并且通过这个样例,很快就可以发现左移一位就相当于乘2,而一般运用得较多的地方也是这里,由于电脑位运算速度较快,所以a=a*2就可以转换为a=a<<1,一来加快速度,二来可以装逼哦。
同理,<<就是相反的含义了,不多解释。
5、& | ^
咋一看和第3项似乎有点像,但是这些都是位运算符,可和第3项也存在一些相通的地方。这些位运算符的共同点是将他们转换为二进制数,然后按位计算,最后返回值。一个个来解释:
① & 和
对于每一位,存在:
1&1=1;1&0=0;0&1=0;0&0=0。
即当且仅当两个数的这一位均为1,返回值为1,否则为0。举一个实例:10&3=[1010](2)&[0011](2)=[0010](2)=2
作为整体时,布尔值返回值在当且仅当每一位返回值均为0时返回0,否则为1。
应用:判断奇偶性的时候,通常会写: if (n%2==0),可写成:if (n&1==0)。
② | 或
对于每一位,存在:
1|1=1;1|0=1;0|1=1;0|0=0。
即两个数的这一位只要有一位为1,返回值为1;否则为0。举一个实例:10|3=[1010](2)|[0011](2)=[1011](2)=11
作为整体时,布尔值返回值在当且仅当每一位返回值均为0时返回0,否则为1。
③^ 异或
对于每一位,存在:
1^1=0;1^0=0;0^1=0;0^0=1。
即两个数的这一位相同时返回1,不同时返回0。举一个实例:10^3=[1010](2)^[0011](2)=[0110](2)=6
作为整体时,布尔值返回值在当且仅当每一位返回值均为0时返回0,否则为1。
应用:这是一个非常强大的位运算符,起码我是这么觉得,因为当我了解到之后都感觉似乎不可能,但是事实证明这是正确的。
<1>更方便地交换两个数的值
-----------------------------------------------------------------------------------------------------
void swap(int &a,int &b) { a^=b; b^=a; a^=b; }
-----------------------------------------------------------------------------------------------------
<2>例题:在一个数列中存在2*n+1个数,其中有n个数出现了两次,一个数出现了一次,请找出那个数。首先容易想到一个算法,作标记,时间复杂度为O(2n)。但是,巧妙地运用^,可以达到O(n),如下代码:
-----------------------------------------------------------------------------------------------------
void find()
{
int ans=0;
for (int i=1;i<=n;i++) ans^=a[i];
printf("%d",ans);
}
-----------------------------------------------------------------------------------------------------