• 短路运算符、位运算总结


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

    & 按位与操作

    • & 左右两侧可以是操作数也可以是布尔表达式
    • 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。

  • 相关阅读:
    JS解析json数据(如何将json字符串转化为数组)
    c/c++学习笔记(11)
    c/c++学习笔记(14)
    c/c++学习笔记(9)
    c/c++概念整理1
    c/c++学习笔记(10)
    c/c++学习笔记(2)
    《c和指针》笔记3
    c/c++学习笔记(3)
    c/c++学习笔记(13)
  • 原文地址:https://www.cnblogs.com/mirage-mc/p/14271772.html
Copyright © 2020-2023  润新知