zoukankan      html  css  js  c++  java
  • C语言-第12课

    第12课 - 位运算符分析

     

    1. 位运算符

    &

    按位与

    ~

    取反

    |

    按位或

    <<

    左移

    ^

    按位异或

    >>

    右移

    C语言是嵌入式开发的首选,我们在进行嵌入式开发的,串口和并口的使用的时候。我们还是要使用位运算的,这样可以更加方便的操作。

    结合律:a&b&c = (a&b)&c = a&(b&c)

    交换律:a&b = b&a

    1. 左移和右移的注意事项

    左移:

    左移运算符<<将运算数的二进制位左移,规则是:高位丢弃,地位补0

    右移:

    右移运算符>>把运算数的二进制位右移,规则是:高位补符号位,地位丢弃。

     

     

    l 0x1<<2+3的值会是什么?

    先算2+3,所以结果为32。加减法的优先级高于位运算符。但是,这种东西,经常慧然人混淆,所以我们引出放错准则。

    1. 防错准则

    避免位运算符,裸机运算符和数学运算符同时出现在一个表达式中。

    当位运算符,逻辑运算符和数学运算符需要同时参与运算的时候,尽量使用括号()来表达计算。

    小技巧:

    左移n位相当于乘以2n次方,但效率比数学运算符高

    右移n位相当于除以2n次方,但效率比数学运算符高

     

    1. 交换两个变量分析

    #include <stdio.h>

    #define SWAP1(a,b)

    {                  

        int temp = a;  

        a = b;         

        b = temp;      

    }

    \用了第三个变量

    #define SWAP2(a,b)

    {                  

        a = a + b;     

        b = a - b;     

        a = a - b;     

    }

    \ 仅仅用了两个变量

    #define SWAP3(a,b)

    {                  

        a = a ^ b;     

        b = a ^ b;     

        a = a ^ b;     

    }

    /*(1)a = a ^ b;

      (2)b = a ^ b = a ^ b ^ b = a ^ (b ^ b) = a ^ 0 = a;

      (3)a = a ^ b = a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b;

      用到了结合律的使用,不会有溢出的可能*/

    int main()

    {

        int a = 1;

        int b = 2;

        SWAP1(a,b);

        SWAP2(a,b);

        SWAP3(a,b);  

        return 0;

    }

    第三种方法很好,因为位运算符是比加减法的运算效率还要高的。

     

    1. 面试题详解:

    有一个数列,其中的自然数都是以偶数的形式出现,只有一个自然数出现的次数为

    奇数次。编写程序找出这个自然数。

    自己编写的函数(找奇数,弄错了):

    #include<stdio.h>

    int main()

    {

    int a[10] = {2,4,6,3,0,12,88,8,10,14};

    int i;

    int k;

    int m;

    for(i=0;i<10;i++)

    {

    k = a[i] % 2;

    if(k == 1)

    m = a[i];

    }

    printf("%d ",m);

    return 0;

    }

    运算结果:3

    教程中的例子:

    #include<stdio.h>

    #define DIM(a) (sizeof(a)/sizeof(*a))

    int main()

    {

    int a[] = {2, 3, 5, 7, 2, 2, 2, 3, 5, 7, 1, 1, 1};

    int find =0;

    int i;

    for(i=0;i<DIM(a);i++)

    {

    find = find ^ a[i];

    }

    printf("find = %d ",find);

    return 0;

    }

    运行结果:find = 1

    1. 思考

    l &&, ||, !&, |, ~的意义是否相同?它们可以在条件表达式中交替使用吗?为什么 ?

    不可以,一个是针对数字,一个是语句中的变量。

    l 1<<32的结果是什么?1<<-1的结果又是什么?为什么 ?

    1默认为unsigned int1左移33位,1已经移出左侧最高位,得到的是0

    1Lunsigned long int1左移33位得到的数据是0x0000000400000000

    1<<-1的结果是0

  • 相关阅读:
    NuGet打包推送批处理以及MSBuild(通用版)
    Linux su和sudo命令的区别,并获得root权限
    linux下命令运行目录上程序前面要加./
    java的系统时间,怎么计算从现在到凌晨还剩下多少时间?
    静态资源压缩(GZIP) 专题
    架构选型之Nodejs与Java
    基于 WebRTC 创建一款多人联机游戏
    django从0到1搭建网站
    Android 关于ExpandableListView去掉里头的分割线
    Android 关于ExpandableListView刷新的解决办法
  • 原文地址:https://www.cnblogs.com/free-1122/p/9706878.html
Copyright © 2011-2022 走看看