美文网首页C语言深度学习
C语言学习第8篇---位运算符使用探究

C语言学习第8篇---位运算符使用探究

作者: CodeAllen | 来源:发表于2019-06-04 22:46 被阅读0次
    0414.jpg

    说明:

    本文原创作者『Allen5G』

    首发于微信公众号『Allen5G』,同时也更新在我的:CSDN简书

    标签:嵌入式软件,算法,架构


    很多新手都对位运算符理解的都不是很深刻,但是位运算在实际编程中使用的却很普遍,因为位运算是直接对bit的操作,效率最高。

    与 &

    1. 计算
    2. 取特定位

    或 |

    1.计算

    2.要将某几位置一,就用与这几位是1的书进行 或


    取反 ~

    1.按位取反(变成二进制取反)


    异或 ^

    两个数不同时为1,否则为0

    1.使特定的位翻转,要将后七位翻转,就与后七位是1的数异或

    2.在不使用临时变量的情况下实现俩个变量的互换

    3.经常用在简单的加密算法上


    左移 << 双目运算符

    左操作数必须为整型

    char 和 short 被隐式转换为int后进行移位操作

    右操作数的范围必须为 :【0,31】

    左移运算符<<将运算符的二进制位左移

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

    右移运算符>>把运算符的二进制位右移

    规则:高位补符号位,低位丢弃

    循环移位:

    left(unsigned value, int n)                                    /*自定义左移函数*/
    
    {
    
        unsigned z;
    
        z = (value >> (32-n)) | (value << n);                        /*循环左移的实现过程*/
    
        return z;
    
    }
    
    image.gif

    循环右移

    right(unsigned value, int n)                                    /*自定义右移函数*/
    
    {
    
        unsigned z;
    
        z = (value << (32-n)) | (value >> n);                        /*循环右移的实现过程*/
    
        return z;
    
    }
    
    image.gif

    位运算

    #include <stdio.h>
    int main()
    {
        printf("%d\n", 3 << 2);
        printf("%d\n", 3 >> 1);
        printf("%d\n", -1 >> 1);
        printf("%d\n", 0x01 << 2 + 3);
    
        printf("%d\n", 3 << -1); // oops!
    
        return 0;
    }
    
    image.gif

    小提示:

    防错的方法:

    ~避免位运算符,逻辑运算符和数学运算符同时出现在一个表达式中

    ~当位运算符,逻辑运算符合数学运算符需要同时参与运算符时,尽量使用括号()来表达计算次序

    小技巧:

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

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

    实验2:交换两个整型变量的值

    #include <stdio.h>
    #define SWAP1(a, b)    \
    {                      \
        int t = a;         \
        a = b;             \
        b = t;             \
    }
    #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;         \
    }
    int main()
    {
        int a = 1;
        int b = 2;
    
        printf("a = %d\n", a);
        printf("b = %d\n", b);
    
        SWAP3(a ,b);
    
        printf("a = %d\n", a);
        printf("b = %d\n", b);
    
        return 0;
    }
    
    image.gif

    实验三:混淆概念的判断条件

    #include <stdio.h>
    int main()
    {
        int i = 0;
        int j = 0;
        int k = 0;
    
        if( ++i | ++j & ++k )
        {
            printf("Run here...\n");
        }
    
        return 0;
    }
    
    image.gif

    位段

    位段类型是一种特殊的结构类型,其所有成员的长度均是以二进制位为单位定义的,结构中的成员被称为位段。位段定义的一般形式为:

    结构 结构名

    {

    类型 变量名1:长度;

    类型 变量名2:长度;

    ……

    类型 变量名n:长度;

    }

    一个位段必须被说明是int、unsigned或signed中的一种

    
    循环移动例子:
    
    #include <stdio.h>
    
    left(unsigned value, int n)                                    /*自定义左移函数*/
    
    {
    
        unsigned z;
    
        z = (value >> (32-n)) | (value << n);                        /*循环左移的实现过程*/ 
    
       return z;
    
    }
    
    right(unsigned value, int n)                                    /*自定义右移函数*/
    
    {
    
        unsigned z;
    
        z = (value << (32-n)) | (value >> n);                        /*循环右移的实现过程*/
    
        return z;
    
    }
    
    main()
    
    {
    
        unsigned a;
    
        int n;
    
        printf("please input a number:\n");
    
        scanf("%o", &a);                                        /*输入一个八进制数*/
    
        printf("please input the number of displacement(>0):\n");
    
        scanf("%d", &n);                                    /*输入要移位的位数*/
    
        printf("the result is %o:\n", left(a, n));                    /*将左移后的结果输出*/
    
        printf("the result is %o:\n", right(a, n));                    /*将右移后的结果输出*/
    
    }
    
    image.gif

    运算符总结:

    算数运算符:

    + - * / %(取余数)

    关系运算符

    > >= < <= !=(不等于) =(等于)

    逻辑运算符

    ! &&(并且) ||(或)

    C语言对真假判断:非零是真

    零是假

    &&左边的表达式为假,右边的肯定是不会执行的

    || 左边的表达式为真 ,右边的表达式肯定不会执行

    赋值运算符:

    = += *= /= -=

    优先级别: 算数>关系>逻辑>赋值



    说明

    1.该文档仅供个人学习使用,版权所有,禁止商用。

    2.本文由我一个人编辑并整理,难免存在一些错误。

    3.为了方便大家平时公交、地铁、外出办事也能用手机随时随地查看该教程,该教程同步更新于微信公众号『Allen5G』。

    关于我

    我的博客:https://blog.csdn.net/super828

    我的GitHub:https://github.com/lkk789

    我的微信公众号(ID:Allen5G)主要分享软件工程师进阶(嵌入式,Linux,C/C++,python,英语),程序员职业发展,如果想查看更多内容,可以关注我的微信公众号『Allen5G』。

    我是Allen,世界500强外企通信软件工程师,每天分享编程,算法,软件进阶知识。欢迎关注我的公众号「Allen5G」,回复「1024」获取最新最全的技术资料,还可以进入技术交流群获取经验方法。

    相关文章

      网友评论

        本文标题:C语言学习第8篇---位运算符使用探究

        本文链接:https://www.haomeiwen.com/subject/xsddxctx.html