zoukankan      html  css  js  c++  java
  • 第16课

    第16课 - 位运算符分析

    1. C语言中的位运算符

        

     C语言中的位运算符直接对 bit 位进行操作,其效率最高。

    2. 左移和右移运算符的注意点

    (1)左操作数必须为整型类型即char、short、int,其中char和short被隐式转换为int后进行移位操作。其它的数据类型,如float等不能进行移位操作。

    (2)C标准规定右操作数的范围为[0,31],如果右操作数不在该范围内,其行为是未定义的,不同的编译器处理方式不同。

    (3)左移运算符 << 将运算数的二进制位左移      

        规则:高位丢弃,低位补0

    (4)右移运算符 >> 将运算数的二进制位右移

        规则:高位补符号位(正数补0,负数补1),低位丢弃

    (5)0x1 << 2 + 3 的值是什么?是1左移两位之后的值4 + 3 = 7吗?   ==>  注意,+ 的优先级大于 << 和 >> 的优先级,即0x1 << 5 等于32

    (6)左移n位相当于乘以2的n次方,但效率比数学运算符高;右移n位相当于除以2的n次方,但效率比数学运算符高

    【位运算符初探】

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     printf("%d
    ", 3 << 2);   // 3 << 2  ==> 11 << 2 ==> 1100,即12
     6     printf("%d
    ", 3 >> 1);   // 11 >> 1,即1
     7     printf("%d
    ", -1 >> 10);       // -1 >> 10 ==> 11111111 11111111 11111111 11111111 >> 10  ==> 11111111 11111111 11111111 11111111 ,即0xffffffff,仍为-1
     8     printf("%d
    ", 0x01 << 2 + 3);  // 相当于0x01 << (2+3),即32
     9     
    10     printf("%d
    ", 3 << -1);  // oops! 右操作数取值范围为[0,31],-1不在该范围内,不同编译器处理方式不同
    11                               // 使用gcc编译,结果为1(将左移-1位当做右移1位,3右移1位结果为1); 使用VS2010编译,结果为0(不符合C标准直接输出0); 使用bcc32编译,结果为-2147483648(int类型的最小值,提醒程序员用法错误)
    12     return 0;
    13 }

    使用gcc编译执行上述代码 

      

    ※※ 避免位运算符逻辑运算符数学运算符同时出现在一个表达式中,如果确实需要同时参与运算,尽量使用括号( )来表达计算次序。

    3. 交换两个整型变量的值

    下面再介绍一下使用位运算符交换两个变量的值。

     1 #include <stdio.h>
     2 
     3 // 使用中间变量交换
     4 #define SWAP1(a, b)    
     5 {                      
     6     int t = a;         
     7     a = b;             
     8     b = t;             
     9 }
    10 
    11 // 使用部分和交换
    12 #define SWAP2(a, b)    
    13 {                      
    14     a = a + b;           // a + b 的值不能溢出
    15     b = a - b;         
    16     a = a - b;         
    17 }
    18 
    19 //使用异或 ^ 交换
    20 #define SWAP3(a, b)    
    21 {                      
    22     a = a ^ b;         
    23     b = a ^ b;         
    24     a = a ^ b;         
    25 }
    26 
    27 int main()
    28 {
    29     int a = 1;
    30     int b = 2;
    31     
    32     
    33     printf("a = %d
    ", a); 
    34     printf("b = %d
    ", b); 
    35     
    36     SWAP3(a ,b);
    37     
    38     printf("a = %d
    ", a); 
    39     printf("b = %d
    ", b); 
    40     
    41     return 0;
    42 }

      swj@ubuntu:~/c_course/ch_16$ ./a.out
      a = 1
      b = 2
      a = 2
      b = 1

    4. 位运算与逻辑运算

    (1)位运算没有短路规则,每个操作数都参与运算

    (2)位运算的结果为整数,而不是 0 或 1

    (3)位运算的优先级高于逻辑运算的优先级

    【混淆概念的判断条件】

    位运算

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     int i = 0;
     6     int j = 0;
     7     int k = 0;
     8     
     9     // 位运算没有短路规则,所有操作数都参与运算
    10     if( ++i | ++j & ++k )
    11     {
    12         printf("Run here...
    ");
    13     }
    14     
    15     printf("i = %d
    ", i);   // 1
    16     printf("j = %d
    ", j);   // 1
    17     printf("k = %d
    ", k);   // 1
    18 
    19     return 0;
    20 }

    逻辑运算

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     int i = 0;
     6     int j = 0;
     7     int k = 0;
     8     
     9     // 短路规则, (true && ++i) || (++j && ++k)
    10     if( ++i || ++j && ++k )
    11     {
    12         printf("Run here...
    ");
    13     }
    14     
    15     printf("i = %d
    ", i);  // 1
    16     printf("j = %d
    ", j);  // 0
    17     printf("k = %d
    ", k);  // 0
    18 
    19     return 0;
    20 }
  • 相关阅读:
    python之re(正则表达式)
    virtualbox之下载地址
    数据库之sqlite
    vmware 虚拟机扩展 liunx系统硬盘空间
    常见python面试题-手写代码系列
    Python的Struct模块
    mac上安装brew如何加速
    outlook数字证书导出、导入及解决老是弹出macOS需要访问系统钥匙串弹窗问题
    docker命令学习
    Message from syslogd不停的打日志
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/11853921.html
Copyright © 2011-2022 走看看