短路运算符、位运算总结

运算符&和&&以及|和||的区别

& 按位与操作

  • & 左右两侧可以是操作数也可以是布尔表达式
  • 1&0=0; 8&28=01000&11100=01000=8;
  • & 左右两侧表达式都会进行计算

&& 短路运算符

  • &&执行时先计算左侧再计算右侧,如果左侧是false,那么右侧就不再计算。
  • 在遇到判断语句的时候,使用&&的效率更高。
  • &&左右两侧只能是布尔表达式

|与||

  • |与||同&、&&类似
  • &&和||称为短路运算符


位运算(&、|、^、~、>>、<<)

位运算概述

计算机中在进行四则运算(+、-、*、/)时,背后原理均为位运算(&、|、^、~、>>、<<)

  • &:与、两位均为1时,结果才为1
  • |:或、两位均为0时,结果才为0
  • ^:异或、两位相同为0,相异为1
  • ~:取反、0变1,1变0
  • <<:左移、各二进位全部左移若干位,高位丢弃,低位补0
  • >>:右移、各二进位全部右移若干位,高位补0,有符号数,各编译器处理方法不同,有的补符号位,有的补0。

按位与运算&

负数按照其补码形式参加按位与运算。

与运算的用途:

  • 1.清零:将一个单元清零,只要与一个各位都为零的数值相与,结果为0。
  • 2.取一个数的指定位:若要取X的低四位,只需找出另一个数Y,使得Y低四位为1,其余位为0,X与Y相与即为X的低四位。
  • 3.判断奇偶:根据最末位是0还是1来决定,为0就是偶数,为1就是奇数。因此可以用if ((a & 1) == 0)代替if (a % 2 == 0)来判断a是不是偶数。

按位或运算 |

负数按照其补码形式参加按位或运算。

或运算的用途:

  • 1.对一个数据的某些位设置为1:与按位与运算取一个数的指定位类似

异或运算 ^

运算规则:0^0=0, 0^1=1, 1^0=1, 1^1=0 (即相同等于0,不同等于1)

异或运算满足的规则:

  • 1.异或运算满足交换律和结合律
  • 2.对任何数x都有x^x=0, x^0=x(自身异或自身为0,自身与0异或为自身)
  • 3.自反性:abb=a^0=a;

异或运算的用途:

  • 1.反转指定位:与1进行异或即可反转
  • 2.与0异或值不变
  • 3.交换两个数(不引入第三变量)
void Swap(int &a, int &b){
    if (a != b){
        a ^= b;//a=a^b
        b ^= a;//b=b^a
        a ^= b;//a=a^b
    }
}

## 取反运算符~ > 取反运算的用途: - 1.使一个数的最低位为0:a&~1

需要注意的是:“~”运算符的优先级比算术运算符、关系运算符、逻辑运算符和其他运算符都要高。

运算符优先级:

  • 第一级:圆括号【()】、下标运bai算符【[]】、分量运算符的指向结构体成员运算符【->】、结构体成员运算符【.】。
  • 第二级:逻辑非运算符【!】、按位取反运算符【~】、自增自减运算符【++ --】、负号运算符【-】、类型转换运算符【(类型)】、指针运算符和取地址运算符【*和&】、长度运算符【sizeof】。
  • 第三级:乘法运算符【*】、除法运算符【/】、取余运算符【%】。
  • 第四级:加法运算符【+】、减法运算符【-】。
  • 第五级:左移动运算符【<<】、右移动运算符【>>】。
  • 第六级:关系运算符【< > <= >= 】。
  • 第七级:等于运算符【==】、不等于运算符【!=】。
  • 第八级:按位与运算符【&】。
  • 第九级:按位异或运算符【^】。
  • 第十级:按位或运算符【|】。
  • 第十一级:逻辑与运算符【&&】。
  • 第十二级:逻辑或运算符【||】。
  • 第十三级:条件运算符【?:】。
  • 第十四级:赋值运算符【= += -= *= /= %= >>= <<.= &= |= ^=】。
  • 第十五级:逗号运算符【,】。

左移运算符<<

定义:将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补零)
注意:若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2

右移运算符>>

定义:将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。

复合赋值运算符

定义:位运算符和赋值运算符结合,组成新的复合赋值运算符

  • &=    例:a&=b 相当于 a=a&b
  • |=    例:a|=b 相当于 a=a|b
  • >>= 例:a>>=b 相当于 a=a>>b
  • <<= 例:a<<=b 相当于 a=a<<b
  • ^=    例:a^=b 相当于 a=a^b

位运算符运用汇总--参考链接

/* -------------判断整数x是奇数还是偶数------------- */
/* 1、常规做法:看除以2的余数 */
if (0 == x % 2)
    偶数
else
   奇数
 
/*2、 使用位运算 */
if (0 == x & 1)
   偶数
else
   奇数
 
/* -------------把r、g、b混合成32位颜色------------- */
#define MAP_RGB(r, g, b)    (((r) << 16) + ((g) << 8) + (b))
#define PIXEL_GET_R(pix)	(((pix) & 0xFF0000) >> 16)
#define PIXEL_GET_G(pix)	(((pix) & 0xFF00) >> 8)
#define PIXEL_GET_B(pix)	(((pix) & 0xFF))
 
/* -------------取整数a的第k位(k=0,1,2,..len(str(a)))-------------  */
int b = a >> k & 1;
 
/* -------------将整数a的第k位清0-------------  */
a = a & ~(1 << k);
 
/* -------------将整数a的第k位置1-------------  */
a = a | (1 << k);
 
/* -------------int型变量循环左移k次-------------  */
a=a<<k|a>>16-k (设sizeof(int)=16)
    
/* ------------- int型变量a循环右移k次-------------  */
a=a<<k|a>>16-k;      // (设sizeof(int)=16)
a=a>>k|a<<16-k;    // (设sizeof(int)=16)
 
/* ------------- 返回X,Y 的平均值-------------  */
int average(int x, int y)
{ 
  return (x&y)+((x^y)>>1);
}
 
/* ------------- 对于一个数 x >= 0,判断是不是2的幂-------------  */
boolean power2(int x)
{
  return ((x&(x-1))==0)&&(x!=0);
}
 
/* ------------- 不用临时变量,交换两个数-------------  */
void swap(int x , int y)
{
    x ^= y;
    y ^= x;
    x ^= y;
}
 
/* ------------- 计算绝对值-------------  */
int abs( int x )
{
    int y ;
    y = x >> 31 ;
    return (x^y)-y ; //or: (x+y)^y
}
 
/* ------------- 取模运算转化成位运算 (在不产生溢出的情况下)-------------  */
a % (2^n) 等价于 a & (2^n - 1)
 
/* ------------- 乘法运算转化成位运算 (在不产生溢出的情况下)-------------  */
a * (2^n) 等价于 a<< n
 
/* ------------- 除法运算转化成位运算 (在不产生溢出的情况下)-------------  */
a / (2^n) 等价于 a>> n
      例: 12/8 == 12>>3
 
/* ------------- 乘法运算转化成位运算 (在不产生溢出的情况下)-------------  */
a * (2^n) 等价于 a<< n
 
if (x == a) x= b;
   else x= a; 等价于 x= a ^ b ^ x;
 
x 的 相反数 表示为 (~x+1)

注意

不同长度的数据进行位运算:如果两个不同长度的数据进行位运算时,系统会将二者按右端对齐,然后进行位运算。

以“与运算”为例说明如下:我们知道在C语言中long型占4个字节,int型占2个字节,如果一个long型数据与一个int型数据进行“与运算“,右端对齐后,左边不足的位依下面三种情况补足,

1)如果整型数据为正数,左边补16个0。

2)如果整型数据为负数,左边补16个1。

3)如果整形数据为无符号数,左边也补16个0。

如:long a=123;int b=1;计算a& b。

如:long a=123;int b=-1;计算a& b。

如:long a=123;unsigned intb=1;计算a & b。

posted @ 2021-01-13 14:15  mirage_mc  阅读(527)  评论(0编辑  收藏  举报